Fix GQL requests failing under chrome #363
- Ref https://github.com/AdguardTeam/AdGuardExtra/issues/599
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
twitch-videoad.js text/javascript
|
||||
(function() {
|
||||
if ( /(^|\.)twitch\.tv$/.test(document.location.hostname) === false ) { return; }
|
||||
var ourTwitchAdSolutionsVersion = 2;// Only bump this when there's a breaking change to Twitch, the script, or there's a conflict with an unmaintained extension which uses this script
|
||||
var ourTwitchAdSolutionsVersion = 3;// Only bump this when there's a breaking change to Twitch, the script, or there's a conflict with an unmaintained extension which uses this script
|
||||
if (window.twitchAdSolutionsVersion && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
||||
console.log("skipping video-swap-new as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
||||
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
||||
@@ -101,6 +101,7 @@ twitch-videoad.js text/javascript
|
||||
return;
|
||||
}
|
||||
var newBlobStr = `
|
||||
const pendingFetchRequests = new Map();
|
||||
${processM3U8.toString()}
|
||||
${hookWorkerFetch.toString()}
|
||||
${declareOptions.toString()}
|
||||
@@ -120,6 +121,23 @@ twitch-videoad.js text/javascript
|
||||
ClientIntegrityHeader = e.data.value;
|
||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||
AuthorizationHeader = e.data.value;
|
||||
} else if (e.data.key == 'FetchResponse') {
|
||||
const responseData = e.data.value;
|
||||
if (pendingFetchRequests.has(responseData.id)) {
|
||||
const { resolve, reject } = pendingFetchRequests.get(responseData.id);
|
||||
pendingFetchRequests.delete(responseData.id);
|
||||
if (responseData.error) {
|
||||
reject(new Error(responseData.error));
|
||||
} else {
|
||||
// Create a Response object from the response data
|
||||
const response = new Response(responseData.body, {
|
||||
status: responseData.status,
|
||||
statusText: responseData.statusText,
|
||||
headers: responseData.headers
|
||||
});
|
||||
resolve(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
hookWorkerFetch();
|
||||
@@ -152,6 +170,16 @@ twitch-videoad.js text/javascript
|
||||
reloadTwitchPlayer(true);
|
||||
}
|
||||
});
|
||||
this.addEventListener('message', async event => {
|
||||
if (event.data.key == 'FetchRequest') {
|
||||
const fetchRequest = event.data.value;
|
||||
const responseData = await handleWorkerFetchRequest(fetchRequest);
|
||||
this.postMessage({
|
||||
key: 'FetchResponse',
|
||||
value: responseData
|
||||
});
|
||||
}
|
||||
});
|
||||
function getAdDiv() {
|
||||
var playerRootDiv = document.querySelector('.video-player');
|
||||
var adDiv = null;
|
||||
@@ -317,7 +345,7 @@ twitch-videoad.js text/javascript
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var encodingsUrl = url;
|
||||
if (i == 1) {
|
||||
var accessTokenResponse = await getAccessToken(channelName, OPT_BACKUP_PLAYER_TYPE, OPT_BACKUP_PLATFORM, realFetch);
|
||||
var accessTokenResponse = await getAccessToken(channelName, OPT_BACKUP_PLAYER_TYPE, OPT_BACKUP_PLATFORM);
|
||||
if (accessTokenResponse != null && accessTokenResponse.status === 200) {
|
||||
var accessToken = await accessTokenResponse.json();
|
||||
var urlInfo = new URL('https://usher.ttvnw.net/api/channel/hls/' + channelName + '.m3u8' + (new URL(url)).search);
|
||||
@@ -416,7 +444,7 @@ twitch-videoad.js text/javascript
|
||||
},
|
||||
}];
|
||||
}
|
||||
function getAccessToken(channelName, playerType, platform, realFetch) {
|
||||
function getAccessToken(channelName, playerType, platform) {
|
||||
if (!platform) {
|
||||
platform = 'web';
|
||||
}
|
||||
@@ -433,23 +461,40 @@ twitch-videoad.js text/javascript
|
||||
'playerType': playerType
|
||||
}
|
||||
};
|
||||
return gqlRequest(body, realFetch);
|
||||
return gqlRequest(body);
|
||||
}
|
||||
function gqlRequest(body, realFetch) {
|
||||
if (ClientIntegrityHeader == null) {
|
||||
//console.warn('ClientIntegrityHeader is null');
|
||||
//throw 'ClientIntegrityHeader is null';
|
||||
}
|
||||
var fetchFunc = realFetch ? realFetch : fetch;
|
||||
return fetchFunc('https://gql.twitch.tv/gql', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
'Client-Id': CLIENT_ID,
|
||||
'Client-Integrity': ClientIntegrityHeader,
|
||||
'X-Device-Id': gql_device_id,
|
||||
'Authorization': AuthorizationHeader
|
||||
function gqlRequest(body) {
|
||||
if (!gql_device_id) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i += 1) {
|
||||
gql_device_id += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
}
|
||||
var headers = {
|
||||
'Client-Id': CLIENT_ID,
|
||||
'Client-Integrity': ClientIntegrityHeader,
|
||||
'X-Device-Id': gql_device_id,
|
||||
'Authorization': AuthorizationHeader
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestId = Math.random().toString(36).substring(2, 15);
|
||||
const fetchRequest = {
|
||||
id: requestId,
|
||||
url: 'https://gql.twitch.tv/gql',
|
||||
options: {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers
|
||||
}
|
||||
};
|
||||
pendingFetchRequests.set(requestId, {
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
postMessage({
|
||||
key: 'FetchRequest',
|
||||
value: fetchRequest
|
||||
});
|
||||
});
|
||||
}
|
||||
function parseAttributes(str) {
|
||||
@@ -528,6 +573,25 @@ twitch-videoad.js text/javascript
|
||||
worker.postMessage({key: key, value: value});
|
||||
});
|
||||
}
|
||||
async function handleWorkerFetchRequest(fetchRequest) {
|
||||
try {
|
||||
const response = await window.fetch(fetchRequest.url, fetchRequest.options);
|
||||
const responseBody = await response.text();
|
||||
const responseObject = {
|
||||
id: fetchRequest.id,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: Object.fromEntries(response.headers.entries()),
|
||||
body: responseBody
|
||||
};
|
||||
return responseObject;
|
||||
} catch (error) {
|
||||
return {
|
||||
id: fetchRequest.id,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
function hookFetch() {
|
||||
var realFetch = window.fetch;
|
||||
window.fetch = function(url, init, ...args) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name TwitchAdSolutions (video-swap-new)
|
||||
// @namespace https://github.com/pixeltris/TwitchAdSolutions
|
||||
// @version 1.35
|
||||
// @version 1.36
|
||||
// @updateURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
||||
// @downloadURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
||||
// @description Multiple solutions for blocking Twitch ads (video-swap-new)
|
||||
@@ -13,7 +13,7 @@
|
||||
// ==/UserScript==
|
||||
(function() {
|
||||
'use strict';
|
||||
var ourTwitchAdSolutionsVersion = 2;// Only bump this when there's a breaking change to Twitch, the script, or there's a conflict with an unmaintained extension which uses this script
|
||||
var ourTwitchAdSolutionsVersion = 3;// Only bump this when there's a breaking change to Twitch, the script, or there's a conflict with an unmaintained extension which uses this script
|
||||
if (window.twitchAdSolutionsVersion && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
||||
console.log("skipping video-swap-new as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
||||
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
||||
@@ -113,6 +113,7 @@
|
||||
return;
|
||||
}
|
||||
var newBlobStr = `
|
||||
const pendingFetchRequests = new Map();
|
||||
${processM3U8.toString()}
|
||||
${hookWorkerFetch.toString()}
|
||||
${declareOptions.toString()}
|
||||
@@ -132,6 +133,23 @@
|
||||
ClientIntegrityHeader = e.data.value;
|
||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||
AuthorizationHeader = e.data.value;
|
||||
} else if (e.data.key == 'FetchResponse') {
|
||||
const responseData = e.data.value;
|
||||
if (pendingFetchRequests.has(responseData.id)) {
|
||||
const { resolve, reject } = pendingFetchRequests.get(responseData.id);
|
||||
pendingFetchRequests.delete(responseData.id);
|
||||
if (responseData.error) {
|
||||
reject(new Error(responseData.error));
|
||||
} else {
|
||||
// Create a Response object from the response data
|
||||
const response = new Response(responseData.body, {
|
||||
status: responseData.status,
|
||||
statusText: responseData.statusText,
|
||||
headers: responseData.headers
|
||||
});
|
||||
resolve(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
hookWorkerFetch();
|
||||
@@ -164,6 +182,16 @@
|
||||
reloadTwitchPlayer(true);
|
||||
}
|
||||
});
|
||||
this.addEventListener('message', async event => {
|
||||
if (event.data.key == 'FetchRequest') {
|
||||
const fetchRequest = event.data.value;
|
||||
const responseData = await handleWorkerFetchRequest(fetchRequest);
|
||||
this.postMessage({
|
||||
key: 'FetchResponse',
|
||||
value: responseData
|
||||
});
|
||||
}
|
||||
});
|
||||
function getAdDiv() {
|
||||
var playerRootDiv = document.querySelector('.video-player');
|
||||
var adDiv = null;
|
||||
@@ -329,7 +357,7 @@
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var encodingsUrl = url;
|
||||
if (i == 1) {
|
||||
var accessTokenResponse = await getAccessToken(channelName, OPT_BACKUP_PLAYER_TYPE, OPT_BACKUP_PLATFORM, realFetch);
|
||||
var accessTokenResponse = await getAccessToken(channelName, OPT_BACKUP_PLAYER_TYPE, OPT_BACKUP_PLATFORM);
|
||||
if (accessTokenResponse != null && accessTokenResponse.status === 200) {
|
||||
var accessToken = await accessTokenResponse.json();
|
||||
var urlInfo = new URL('https://usher.ttvnw.net/api/channel/hls/' + channelName + '.m3u8' + (new URL(url)).search);
|
||||
@@ -428,7 +456,7 @@
|
||||
},
|
||||
}];
|
||||
}
|
||||
function getAccessToken(channelName, playerType, platform, realFetch) {
|
||||
function getAccessToken(channelName, playerType, platform) {
|
||||
if (!platform) {
|
||||
platform = 'web';
|
||||
}
|
||||
@@ -445,23 +473,40 @@
|
||||
'playerType': playerType
|
||||
}
|
||||
};
|
||||
return gqlRequest(body, realFetch);
|
||||
return gqlRequest(body);
|
||||
}
|
||||
function gqlRequest(body, realFetch) {
|
||||
if (ClientIntegrityHeader == null) {
|
||||
//console.warn('ClientIntegrityHeader is null');
|
||||
//throw 'ClientIntegrityHeader is null';
|
||||
}
|
||||
var fetchFunc = realFetch ? realFetch : fetch;
|
||||
return fetchFunc('https://gql.twitch.tv/gql', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
'Client-Id': CLIENT_ID,
|
||||
'Client-Integrity': ClientIntegrityHeader,
|
||||
'X-Device-Id': gql_device_id,
|
||||
'Authorization': AuthorizationHeader
|
||||
function gqlRequest(body) {
|
||||
if (!gql_device_id) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i += 1) {
|
||||
gql_device_id += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
}
|
||||
var headers = {
|
||||
'Client-Id': CLIENT_ID,
|
||||
'Client-Integrity': ClientIntegrityHeader,
|
||||
'X-Device-Id': gql_device_id,
|
||||
'Authorization': AuthorizationHeader
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
const requestId = Math.random().toString(36).substring(2, 15);
|
||||
const fetchRequest = {
|
||||
id: requestId,
|
||||
url: 'https://gql.twitch.tv/gql',
|
||||
options: {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers
|
||||
}
|
||||
};
|
||||
pendingFetchRequests.set(requestId, {
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
postMessage({
|
||||
key: 'FetchRequest',
|
||||
value: fetchRequest
|
||||
});
|
||||
});
|
||||
}
|
||||
function parseAttributes(str) {
|
||||
@@ -540,6 +585,25 @@
|
||||
worker.postMessage({key: key, value: value});
|
||||
});
|
||||
}
|
||||
async function handleWorkerFetchRequest(fetchRequest) {
|
||||
try {
|
||||
const response = await window.fetch(fetchRequest.url, fetchRequest.options);
|
||||
const responseBody = await response.text();
|
||||
const responseObject = {
|
||||
id: fetchRequest.id,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: Object.fromEntries(response.headers.entries()),
|
||||
body: responseBody
|
||||
};
|
||||
return responseObject;
|
||||
} catch (error) {
|
||||
return {
|
||||
id: fetchRequest.id,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
function hookFetch() {
|
||||
var realFetch = window.fetch;
|
||||
window.fetch = function(url, init, ...args) {
|
||||
|
||||
Reference in New Issue
Block a user