fix(player): vikingfile dostawal adres reklamy zamiast filmu
Wyjscie z wstrzykiwanego skryptu dla stron z Turnstile siedzialo w tym samym try co oswajanie strony vikingfile. Skrypt startuje przed powstaniem <html>, appendChild na null rzucal, a catch omijal return. Na vikingfile szedl caly skrypt ekstrakcji i podsluch fetch bral zapytanie Adcash (adexchangerapid.com/...&cbtitle=<plik>.mp4) za film: "None of the available extractors" albo brak polaczenia z adexchangerapid przy blokadzie reklam, polowa odtworzen galaxyporn. Host liczony na poczatku, wyjscie poza try, styl dokladany po zaladowaniu DOM, podsluch tylko na POST do wlasnej domeny, zapas z <video>.src. Domeny Adcash na liscie reklam. Sprawdzone na emulatorze przez DevTools WebView: stara paczka 3x blad, nowa gra (link z POST vikingfile). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ba53f872d2
commit
3b127bff3d
2 changed files with 72 additions and 26 deletions
|
|
@ -35,6 +35,13 @@ export type ChangelogEntry = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CHANGELOG: ChangelogEntry[] = [
|
export const CHANGELOG: ChangelogEntry[] = [
|
||||||
|
{
|
||||||
|
id: '2026-10-02b',
|
||||||
|
date: 'October 2026',
|
||||||
|
items: [
|
||||||
|
'Galaxyporn: about half of the plays ended with "Playback failed". The app grabbed the address of an ad on the vikingfile page and tried to play it as the video. It now waits for the real file.',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: '2026-10-02a',
|
id: '2026-10-02a',
|
||||||
date: 'October 2026',
|
date: 'October 2026',
|
||||||
|
|
|
||||||
|
|
@ -1281,6 +1281,18 @@ const INJECTED_JS = `
|
||||||
// podsluchujemy POST zwracajacy bezposredni link. NICZEGO nie chowamy: pierwsza
|
// podsluchujemy POST zwracajacy bezposredni link. NICZEGO nie chowamy: pierwsza
|
||||||
// wersja chowala oprawe strony i przy nierenderujacym sie widgecie zostawal
|
// wersja chowala oprawe strony i przy nierenderujacym sie widgecie zostawal
|
||||||
// czarny ekran, gorzej niz przed zmiana.
|
// czarny ekran, gorzej niz przed zmiana.
|
||||||
|
//
|
||||||
|
// Host sprawdzamy NA POCZATKU i wychodzimy POZA blokiem try. Wczesniej wyjscie
|
||||||
|
// siedzialo w tym samym try co oswajanie strony, a skrypt rusza, zanim powstanie
|
||||||
|
// <html>: appendChild na null rzucal, catch polykal blad i omijal return. Na
|
||||||
|
// vikingfile szedl wiec caly skrypt ponizej, a podsluch fetch bral zapytanie
|
||||||
|
// reklamy Adcash (adexchangerapid.com/...&cbtitle=<nazwa pliku>.mp4) za film.
|
||||||
|
// Telemetria: ~155 bledow "None of the available extractors" i ~50 "adexchangerapid"
|
||||||
|
// tygodniowo, polowa odtworzen galaxyporn. Dowod z emulatora 2026-10-02.
|
||||||
|
var goonTurnstileHost = false;
|
||||||
|
try {
|
||||||
|
goonTurnstileHost = /vik[i1]ngfile\\.|playmogo\\.|dood|d0000d|dooood|do0od|do7go|ds2play|doply\\.|myvidplay\\./i.test(location.hostname);
|
||||||
|
} catch (e) {}
|
||||||
try {
|
try {
|
||||||
if (/vik[i1]ngfile\\./i.test(location.hostname)) {
|
if (/vik[i1]ngfile\\./i.test(location.hostname)) {
|
||||||
// UWAGA: NIE chowamy tu reszty strony. Pierwsza wersja robila dokladnie to i user
|
// UWAGA: NIE chowamy tu reszty strony. Pierwsza wersja robila dokladnie to i user
|
||||||
|
|
@ -1288,6 +1300,12 @@ const INJECTED_JS = `
|
||||||
// wyrenderuje, na czarnym tle nie zostaje juz nic. Gorsze niz stan wyjsciowy. Teraz
|
// wyrenderuje, na czarnym tle nie zostaje juz nic. Gorsze niz stan wyjsciowy. Teraz
|
||||||
// tylko podswietlamy wlasciwe miejsce i przewijamy do niego, wiec najgorszy przypadek
|
// tylko podswietlamy wlasciwe miejsce i przewijamy do niego, wiec najgorszy przypadek
|
||||||
// to normalna strona hostera, czyli to, co user widzial przed ta zmiana.
|
// to normalna strona hostera, czyli to, co user widzial przed ta zmiana.
|
||||||
|
var vkSent = false;
|
||||||
|
var vkSendUrl = function(u) {
|
||||||
|
if (vkSent || !/^https?:/i.test(u || '') || !window.ReactNativeWebView) return;
|
||||||
|
vkSent = true;
|
||||||
|
window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'video_url', url: u }));
|
||||||
|
};
|
||||||
var vkCss = document.createElement('style');
|
var vkCss = document.createElement('style');
|
||||||
vkCss.textContent = [
|
vkCss.textContent = [
|
||||||
'#captcha-download{outline:2px solid #e05a6d!important;border-radius:10px!important;',
|
'#captcha-download{outline:2px solid #e05a6d!important;border-radius:10px!important;',
|
||||||
|
|
@ -1295,9 +1313,17 @@ const INJECTED_JS = `
|
||||||
'#goon-vk-hint{color:#e05a6d;font:600 15px system-ui,sans-serif;text-align:center;',
|
'#goon-vk-hint{color:#e05a6d;font:600 15px system-ui,sans-serif;text-align:center;',
|
||||||
'padding:8px 0}',
|
'padding:8px 0}',
|
||||||
].join('');
|
].join('');
|
||||||
(document.head || document.documentElement).appendChild(vkCss);
|
|
||||||
var vkScrolled = false;
|
var vkScrolled = false;
|
||||||
var vkReady = function() {
|
var vkReady = function() {
|
||||||
|
// Styl dokladamy dopiero tutaj: na starcie skryptu nie ma jeszcze ani <head>,
|
||||||
|
// ani <html> (patrz komentarz przy goonTurnstileHost).
|
||||||
|
if (!vkCss.parentNode) {
|
||||||
|
var vkRoot = document.head || document.documentElement;
|
||||||
|
if (vkRoot) vkRoot.appendChild(vkCss);
|
||||||
|
}
|
||||||
|
// Zapas dla podsluchu nizej: strona sama wpisuje link do <video>, gdy to plik wideo.
|
||||||
|
var vkVideo = document.querySelector('video');
|
||||||
|
if (vkVideo && /^https?:/i.test(vkVideo.src || '')) vkSendUrl(vkVideo.src);
|
||||||
var box = document.getElementById('captcha-download');
|
var box = document.getElementById('captcha-download');
|
||||||
if (box && !document.getElementById('goon-vk-hint')) {
|
if (box && !document.getElementById('goon-vk-hint')) {
|
||||||
var hint = document.createElement('div');
|
var hint = document.createElement('div');
|
||||||
|
|
@ -1338,26 +1364,36 @@ const INJECTED_JS = `
|
||||||
// gdy tylko link sie pojawi, oddajemy go aplikacji, ktora przechodzi na natywny
|
// gdy tylko link sie pojawi, oddajemy go aplikacji, ktora przechodzi na natywny
|
||||||
// odtwarzacz. Oswojony wyglad strony zostaje jako zabezpieczenie na wypadek, gdyby
|
// odtwarzacz. Oswojony wyglad strony zostaje jako zabezpieczenie na wypadek, gdyby
|
||||||
// zabezpieczenie jednak zazadalo kliniecia.
|
// zabezpieczenie jednak zazadalo kliniecia.
|
||||||
|
//
|
||||||
|
// Bierzemy tylko odpowiedz na POST do wlasnej domeny strony: skrypty reklam tez
|
||||||
|
// robia zapytania i ich JSON-y bywaja podobne.
|
||||||
var vkOpen = XMLHttpRequest.prototype.open;
|
var vkOpen = XMLHttpRequest.prototype.open;
|
||||||
var vkSend = XMLHttpRequest.prototype.send;
|
var vkSend = XMLHttpRequest.prototype.send;
|
||||||
XMLHttpRequest.prototype.open = function() { return vkOpen.apply(this, arguments); };
|
XMLHttpRequest.prototype.open = function(method, reqUrl) {
|
||||||
|
try {
|
||||||
|
this.__goonVkOwn = String(method).toUpperCase() === 'POST' &&
|
||||||
|
new URL(String(reqUrl), location.href).origin === location.origin;
|
||||||
|
} catch (e) {
|
||||||
|
this.__goonVkOwn = false;
|
||||||
|
}
|
||||||
|
return vkOpen.apply(this, arguments);
|
||||||
|
};
|
||||||
XMLHttpRequest.prototype.send = function() {
|
XMLHttpRequest.prototype.send = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
try {
|
try {
|
||||||
|
if (self.__goonVkOwn) {
|
||||||
self.addEventListener('load', function() {
|
self.addEventListener('load', function() {
|
||||||
try {
|
try {
|
||||||
var j = JSON.parse(self.responseText);
|
var j = JSON.parse(self.responseText);
|
||||||
if (j && j.link && window.ReactNativeWebView) {
|
if (j && typeof j.link === 'string') vkSendUrl(j.link);
|
||||||
window.ReactNativeWebView.postMessage(
|
|
||||||
JSON.stringify({ type: 'video_url', url: j.link })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
return vkSend.apply(this, arguments);
|
return vkSend.apply(this, arguments);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} catch (e) {}
|
||||||
// Na KAZDYM hosterze z brama Cloudflare KONCZYMY tutaj. Ponizej patchujemy prototypy
|
// Na KAZDYM hosterze z brama Cloudflare KONCZYMY tutaj. Ponizej patchujemy prototypy
|
||||||
// HTMLMediaElement, klikamy w plakat i usuwamy elementy uznane za reklamy, a Turnstile
|
// HTMLMediaElement, klikamy w plakat i usuwamy elementy uznane za reklamy, a Turnstile
|
||||||
// potrafi uznac tak zmodyfikowane srodowisko za podejrzane i odrzucic weryfikacje
|
// potrafi uznac tak zmodyfikowane srodowisko za podejrzane i odrzucic weryfikacje
|
||||||
|
|
@ -1371,8 +1407,7 @@ const INJECTED_JS = `
|
||||||
//
|
//
|
||||||
// Na stronie pliku i tak nie potrzebujemy ani wyciszania autoplay, ani ad-blocka,
|
// Na stronie pliku i tak nie potrzebujemy ani wyciszania autoplay, ani ad-blocka,
|
||||||
// a bezposredni link przechwytujemy podsluchem powyzej.
|
// a bezposredni link przechwytujemy podsluchem powyzej.
|
||||||
if (/vik[i1]ngfile\\.|playmogo\\.|dood|d0000d|dooood|do0od|do7go|ds2play|doply\\.|myvidplay\\./i.test(location.hostname)) return;
|
if (goonTurnstileHost) return;
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
// -- 0a. Mute autoplay until the FIRST user gesture (kills the unmuted-audio flash
|
// -- 0a. Mute autoplay until the FIRST user gesture (kills the unmuted-audio flash
|
||||||
// gdy WebView otwiera stronę żeby przechwycić stream, report dccc05e4).
|
// gdy WebView otwiera stronę żeby przechwycić stream, report dccc05e4).
|
||||||
|
|
@ -1495,6 +1530,10 @@ const INJECTED_JS = `
|
||||||
// ("zacina się na pierwszych sekundach i robi loop", bug-reports 40ec88cc / 92e9133e).
|
// ("zacina się na pierwszych sekundach i robi loop", bug-reports 40ec88cc / 92e9133e).
|
||||||
// isLikelyAd odsiewał je już przy auto-extrakcji, ale sama strona i tak je ładowała.
|
// isLikelyAd odsiewał je już przy auto-extrakcji, ale sama strona i tak je ładowała.
|
||||||
'opencdn.b-cdn.net',
|
'opencdn.b-cdn.net',
|
||||||
|
// Adcash: zapytanie o reklame niesie tytul strony w parametrze (cbtitle=<plik>.mp4),
|
||||||
|
// a VIDEO_RE widzi ".mp4" takze w parametrach. Tak reklama trafiala do odtwarzacza
|
||||||
|
// na vikingfile (2026-10-02).
|
||||||
|
'adexchangerapid.com','usrpubtrk.com',
|
||||||
];
|
];
|
||||||
const isAdHost = function(url) {
|
const isAdHost = function(url) {
|
||||||
if (!url) return false;
|
if (!url) return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue