this repo has no description

browser: Cleanup

Rewrote the blocking logic to be similar to desktop injector (nascar).
Also fixed extension repositories not loading on Firefox due to the
User-Agent header.

Changed files
+118 -138
packages
+2 -1
packages/browser/blockLoading.json
···
"type": "block"
},
"condition": {
-
"urlFilter": "*://discord.com/assets/*.js",
"resourceTypes": ["script"]
}
}
···
"type": "block"
},
"condition": {
+
"requestDomains": ["discord.com", "discordapp.com"],
+
"urlFilter": "*/assets/*.js",
"resourceTypes": ["script"]
}
}
+8 -3
packages/browser/manifest.json
···
"description": "Yet another Discord mod",
"version": "1.3.11",
"permissions": ["declarativeNetRequestWithHostAccess", "webRequest", "scripting", "webNavigation"],
-
"host_permissions": ["https://moonlight-mod.github.io/*", "https://api.github.com/*", "https://*.discord.com/*"],
"content_scripts": [
{
"js": ["index.js"],
-
"matches": ["https://*.discord.com/*"],
"run_at": "document_start",
"world": "MAIN"
}
···
"web_accessible_resources": [
{
"resources": ["index.js"],
-
"matches": ["https://*.discord.com/*"]
}
]
}
···
"description": "Yet another Discord mod",
"version": "1.3.11",
"permissions": ["declarativeNetRequestWithHostAccess", "webRequest", "scripting", "webNavigation"],
+
"host_permissions": [
+
"https://moonlight-mod.github.io/*",
+
"https://api.github.com/*",
+
"https://*.discord.com/*",
+
"https://*.discordapp.com/*"
+
],
"content_scripts": [
{
"js": ["index.js"],
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"],
"run_at": "document_start",
"world": "MAIN"
}
···
"web_accessible_resources": [
{
"resources": ["index.js"],
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"]
}
]
}
+4 -4
packages/browser/manifestv2.json
···
"webRequestBlocking",
"scripting",
"webNavigation",
-
"https://*.discord.com/assets/*.js",
"https://moonlight-mod.github.io/*",
-
"https://api.github.com/*",
-
"https://*.discord.com/*"
],
"background": {
"scripts": ["background.js"]
···
"content_scripts": [
{
"js": ["index.js"],
-
"matches": ["https://*.discord.com/*"],
"run_at": "document_start",
"world": "MAIN"
}
···
"webRequestBlocking",
"scripting",
"webNavigation",
+
"https://*.discord.com/*",
+
"https://*.discordapp.com/*",
"https://moonlight-mod.github.io/*",
+
"https://api.github.com/*"
],
"background": {
"scripts": ["background.js"]
···
"content_scripts": [
{
"js": ["index.js"],
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"],
"run_at": "document_start",
"world": "MAIN"
}
+55 -70
packages/browser/src/background-mv2.js
···
/* eslint-disable no-console */
/* eslint-disable no-undef */
-
const starterUrls = ["web.", "sentry."];
-
let blockLoading = true;
-
let doing = false;
-
let collectedUrls = new Set();
-
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
-
const url = new URL(details.url);
-
if (!blockLoading && url.hostname.endsWith("discord.com")) {
-
console.log("Blocking", details.url);
-
blockLoading = true;
-
collectedUrls.clear();
-
}
-
});
-
async function doTheThing(urls, tabId) {
-
console.log("Doing", urls, tabId);
-
blockLoading = false;
-
try {
-
await chrome.scripting.executeScript({
-
target: { tabId },
-
world: "MAIN",
-
args: [urls],
-
func: async (urls) => {
-
try {
-
await window._moonlightBrowserInit();
-
} catch (e) {
-
console.log(e);
-
}
-
const scripts = [...document.querySelectorAll("script")].filter(
-
(script) => script.src && urls.some((url) => url.includes(script.src))
-
);
-
// backwards
-
urls.reverse();
-
for (const url of urls) {
-
const script = scripts.find((script) => url.includes(script.src));
-
console.log("adding new script", script);
-
const newScript = document.createElement("script");
-
for (const { name, value } of script.attributes) {
-
newScript.setAttribute(name, value);
}
-
-
script.remove();
-
document.documentElement.appendChild(newScript);
-
}
-
}
-
});
-
} catch (e) {
-
console.log(e);
-
}
-
-
doing = false;
-
collectedUrls.clear();
-
}
-
-
chrome.webRequest.onBeforeRequest.addListener(
-
async (details) => {
-
if (starterUrls.some((url) => details.url.includes(url))) {
-
console.log("Adding", details.url);
-
collectedUrls.add(details.url);
}
-
if (collectedUrls.size === starterUrls.length) {
-
if (doing) return;
-
if (!blockLoading) return;
-
doing = true;
-
const urls = [...collectedUrls];
-
const tabId = details.tabId;
-
-
// yes this is a load-bearing sleep
-
setTimeout(() => doTheThing(urls, tabId), 0);
-
}
-
-
if (blockLoading) return { cancel: true };
},
{
-
urls: ["https://*.discord.com/assets/*.js"]
},
["blocking"]
);
···
)
};
},
-
{ urls: ["https://*.discord.com/*"] },
["blocking", "responseHeaders"]
);
···
/* eslint-disable no-console */
/* eslint-disable no-undef */
+
const scriptUrls = ["web.", "sentry."];
+
let blockedScripts = new Set();
+
chrome.webRequest.onBeforeRequest.addListener(
+
async (details) => {
+
if (details.tabId === -1) return;
+
const url = new URL(details.url);
+
const hasUrl = scriptUrls.some((scriptUrl) => {
+
return (
+
details.url.includes(scriptUrl) &&
+
!url.searchParams.has("inj") &&
+
(url.host.endsWith("discord.com") || url.host.endsWith("discordapp.com"))
+
);
+
});
+
if (hasUrl) blockedScripts.add(details.url);
+
if (blockedScripts.size === scriptUrls.length) {
+
const blockedScriptsCopy = Array.from(blockedScripts);
+
blockedScripts.clear();
+
setTimeout(async () => {
+
console.log("Starting moonlight");
+
await chrome.scripting.executeScript({
+
target: { tabId: details.tabId },
+
world: "MAIN",
+
args: [blockedScriptsCopy],
+
func: async (blockedScripts) => {
+
console.log("Initializing moonlight");
+
try {
+
await window._moonlightBrowserInit();
+
} catch (e) {
+
console.error(e);
+
}
+
console.log("Readding scripts");
+
try {
+
const scripts = [...document.querySelectorAll("script")].filter(
+
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
+
);
+
blockedScripts.reverse();
+
for (const url of blockedScripts) {
+
if (url.includes("/sentry.")) continue;
+
const script = scripts.find((script) => url.includes(script.src));
+
const newScript = document.createElement("script");
+
for (const attr of script.attributes) {
+
if (attr.name === "src") attr.value += "?inj";
+
newScript.setAttribute(attr.name, attr.value);
+
}
+
script.remove();
+
document.documentElement.appendChild(newScript);
+
}
+
} catch (e) {
+
console.error(e);
+
}
}
+
});
+
}, 0);
}
+
if (hasUrl) return { cancel: true };
},
{
+
urls: ["https://*.discord.com/assets/*.js", "https://*.discordapp.com/assets/*.js"]
},
["blocking"]
);
···
)
};
},
+
{ urls: ["https://*.discord.com/*", "https://*.discordapp.com/*"] },
["blocking", "responseHeaders"]
);
+37 -39
packages/browser/src/background.js
···
/* eslint-disable no-console */
/* eslint-disable no-undef */
-
const starterUrls = ["web.", "sentry."];
-
let blockLoading = true;
-
let doing = false;
-
let collectedUrls = new Set();
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
const url = new URL(details.url);
-
if (!blockLoading && url.hostname.endsWith("discord.com")) {
await chrome.declarativeNetRequest.updateEnabledRulesets({
enableRulesetIds: ["modifyResponseHeaders", "blockLoading"]
});
-
blockLoading = true;
-
collectedUrls.clear();
}
});
chrome.webRequest.onBeforeRequest.addListener(
async (details) => {
if (details.tabId === -1) return;
-
if (starterUrls.some((url) => details.url.includes(url))) {
-
console.log("Adding", details.url);
-
collectedUrls.add(details.url);
-
}
-
if (collectedUrls.size === starterUrls.length) {
-
if (doing) return;
-
if (!blockLoading) return;
-
doing = true;
-
const urls = [...collectedUrls];
-
console.log("Doing", urls);
console.log("Running moonlight script");
try {
···
files: ["index.js"]
});
} catch (e) {
-
console.log(e);
}
console.log("Initializing moonlight");
···
try {
await window._moonlightBrowserInit();
} catch (e) {
-
console.log(e);
}
}
});
···
console.log(e);
}
-
console.log("Updating rulesets");
try {
-
blockLoading = false;
await chrome.declarativeNetRequest.updateEnabledRulesets({
disableRulesetIds: ["blockLoading"],
enableRulesetIds: ["modifyResponseHeaders"]
});
} catch (e) {
-
console.log(e);
}
console.log("Readding scripts");
···
await chrome.scripting.executeScript({
target: { tabId: details.tabId },
world: "MAIN",
-
args: [urls],
-
func: async (urls) => {
const scripts = [...document.querySelectorAll("script")].filter(
-
(script) => script.src && urls.some((url) => url.includes(script.src))
);
-
// backwards
-
urls.reverse();
-
for (const url of urls) {
-
const script = scripts.find((script) => url.includes(script.src));
-
console.log("adding new script", script);
const newScript = document.createElement("script");
-
for (const { name, value } of script.attributes) {
-
newScript.setAttribute(name, value);
}
-
script.remove();
document.documentElement.appendChild(newScript);
}
}
});
} catch (e) {
-
console.log(e);
}
-
-
console.log("Done");
-
doing = false;
-
collectedUrls.clear();
}
},
{
-
urls: ["*://*.discord.com/assets/*.js"]
}
);
···
/* eslint-disable no-console */
/* eslint-disable no-undef */
+
const scriptUrls = ["web.", "sentry."];
+
let blockedScripts = new Set();
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
const url = new URL(details.url);
+
if (
+
!url.searchParams.has("inj") &&
+
(url.hostname.endsWith("discord.com") || url.hostname.endsWith("discordapp.com"))
+
) {
+
console.log("Enabling block ruleset");
await chrome.declarativeNetRequest.updateEnabledRulesets({
enableRulesetIds: ["modifyResponseHeaders", "blockLoading"]
});
}
});
chrome.webRequest.onBeforeRequest.addListener(
async (details) => {
if (details.tabId === -1) return;
+
const url = new URL(details.url);
+
const hasUrl = scriptUrls.some((scriptUrl) => {
+
return (
+
details.url.includes(scriptUrl) &&
+
!url.searchParams.has("inj") &&
+
(url.hostname.endsWith("discord.com") || url.hostname.endsWith("discordapp.com"))
+
);
+
});
+
+
if (hasUrl) blockedScripts.add(details.url);
+
+
if (blockedScripts.size === scriptUrls.length) {
+
const blockedScriptsCopy = Array.from(blockedScripts);
+
blockedScripts.clear();
console.log("Running moonlight script");
try {
···
files: ["index.js"]
});
} catch (e) {
+
console.error(e);
}
console.log("Initializing moonlight");
···
try {
await window._moonlightBrowserInit();
} catch (e) {
+
console.error(e);
}
}
});
···
console.log(e);
}
+
console.log("Disabling block ruleset");
try {
await chrome.declarativeNetRequest.updateEnabledRulesets({
disableRulesetIds: ["blockLoading"],
enableRulesetIds: ["modifyResponseHeaders"]
});
} catch (e) {
+
console.error(e);
}
console.log("Readding scripts");
···
await chrome.scripting.executeScript({
target: { tabId: details.tabId },
world: "MAIN",
+
args: [blockedScriptsCopy],
+
func: async (blockedScripts) => {
const scripts = [...document.querySelectorAll("script")].filter(
+
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
);
+
blockedScripts.reverse();
+
for (const url of blockedScripts) {
+
if (url.includes("/sentry.")) continue;
+
const script = scripts.find((script) => url.includes(script.src));
const newScript = document.createElement("script");
+
for (const attr of script.attributes) {
+
if (attr.name === "src") attr.value += "?inj";
+
newScript.setAttribute(attr.name, attr.value);
}
script.remove();
document.documentElement.appendChild(newScript);
}
}
});
} catch (e) {
+
console.error(e);
}
}
},
{
+
urls: ["*://*.discord.com/assets/*.js", "*://*.discordapp.com/assets/*.js"]
}
);
+12 -21
packages/core-extensions/src/moonbase/native.ts
···
export const userAgent = `moonlight/${moonlightGlobal.version} (https://github.com/moonlight-mod/moonlight)`;
async function getStableRelease(): Promise<{
name: string;
assets: {
···
}> {
const req = await fetch(githubApiUrl, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
return await req.json();
}
···
} else if (moonlightGlobal.branch === MoonlightBranch.NIGHTLY) {
const req = await fetch(nightlyRefUrl, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
const ref = (await req.text()).split("\n")[0];
return ref !== moonlightGlobal.version ? ref : null;
···
logger.debug(`Downloading ${asset.browser_download_url}`);
const req = await fetch(asset.browser_download_url, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
return [await req.arrayBuffer(), json.name];
···
logger.debug(`Downloading ${nightlyZipUrl}`);
const zipReq = await fetch(nightlyZipUrl, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
const refReq = await fetch(nightlyRefUrl, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
const ref = (await refReq.text()).split("\n")[0];
···
try {
const req = await fetch(repo, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
const json = await req.json();
ret[repo] = json;
···
async installExtension(manifest, url, repo) {
const req = await fetch(url, {
cache: "no-store",
-
headers: {
-
"User-Agent": userAgent
-
}
});
const dir = moonlightGlobal.getExtensionDir(manifest.id);
···
export const userAgent = `moonlight/${moonlightGlobal.version} (https://github.com/moonlight-mod/moonlight)`;
+
// User-Agent header causes trouble on Firefox
+
const isBrowser = globalThis.moonlightNode != null && globalThis.moonlightNode.isBrowser;
+
const sharedHeaders: Record<string, string> = {};
+
if (!isBrowser) sharedHeaders["User-Agent"] = userAgent;
+
async function getStableRelease(): Promise<{
name: string;
assets: {
···
}> {
const req = await fetch(githubApiUrl, {
cache: "no-store",
+
headers: sharedHeaders
});
return await req.json();
}
···
} else if (moonlightGlobal.branch === MoonlightBranch.NIGHTLY) {
const req = await fetch(nightlyRefUrl, {
cache: "no-store",
+
headers: sharedHeaders
});
const ref = (await req.text()).split("\n")[0];
return ref !== moonlightGlobal.version ? ref : null;
···
logger.debug(`Downloading ${asset.browser_download_url}`);
const req = await fetch(asset.browser_download_url, {
cache: "no-store",
+
headers: sharedHeaders
});
return [await req.arrayBuffer(), json.name];
···
logger.debug(`Downloading ${nightlyZipUrl}`);
const zipReq = await fetch(nightlyZipUrl, {
cache: "no-store",
+
headers: sharedHeaders
});
const refReq = await fetch(nightlyRefUrl, {
cache: "no-store",
+
headers: sharedHeaders
});
const ref = (await refReq.text()).split("\n")[0];
···
try {
const req = await fetch(repo, {
cache: "no-store",
+
headers: sharedHeaders
});
const json = await req.json();
ret[repo] = json;
···
async installExtension(manifest, url, repo) {
const req = await fetch(url, {
cache: "no-store",
+
headers: sharedHeaders
});
const dir = moonlightGlobal.getExtensionDir(manifest.id);