this repo has no description

Delay Discord loading in the worst way possible

+19 -9
build.mjs
···
dest: "./dist/browser/manifest.json"
})
);
-
plugins.push(
-
copyStaticFiles({
-
src: "./packages/browser/modifyResponseHeaders.json",
-
dest: "./dist/browser/modifyResponseHeaders.json"
-
})
-
);
-
if (mv2) {
+
+
if (!mv2) {
plugins.push(
copyStaticFiles({
-
src: "./packages/browser/src/background.js",
-
dest: "./dist/browser/background.js"
+
src: "./packages/browser/modifyResponseHeaders.json",
+
dest: "./dist/browser/modifyResponseHeaders.json"
+
})
+
);
+
plugins.push(
+
copyStaticFiles({
+
src: "./packages/browser/blockLoading.json",
+
dest: "./dist/browser/blockLoading.json"
})
);
}
+
+
plugins.push(
+
copyStaticFiles({
+
src: mv2
+
? "./packages/browser/src/background-mv2.js"
+
: "./packages/browser/src/background.js",
+
dest: "./dist/browser/background.js"
+
})
+
);
}
/** @type {import("esbuild").BuildOptions} */
+13
packages/browser/blockLoading.json
···
+
[
+
{
+
"id": 2,
+
"priority": 1,
+
"action": {
+
"type": "block"
+
},
+
"condition": {
+
"urlFilter": "*://discord.com/assets/*.js",
+
"resourceTypes": ["script"]
+
}
+
}
+
]
+26 -6
packages/browser/manifest.json
···
"name": "moonlight",
"description": "Yet another Discord mod",
"version": "1.1.0",
-
"permissions": ["declarativeNetRequestWithHostAccess"],
+
"permissions": [
+
"declarativeNetRequestWithHostAccess",
+
"webRequest",
+
"scripting",
+
"webNavigation"
+
],
+
"host_permissions": [
+
"https://moonlight-mod.github.io/*",
+
"https://*.discord.com/*"
+
],
"content_scripts": [
{
"js": ["index.js"],
···
"world": "MAIN"
}
],
-
"host_permissions": [
-
"https://moonlight-mod.github.io/*",
-
"https://*.discord.com/*"
-
],
"declarative_net_request": {
"rule_resources": [
{
"id": "modifyResponseHeaders",
"enabled": true,
"path": "modifyResponseHeaders.json"
+
},
+
{
+
"id": "blockLoading",
+
"enabled": true,
+
"path": "blockLoading.json"
}
]
-
}
+
},
+
"background": {
+
"service_worker": "background.js",
+
"type": "module"
+
},
+
"web_accessible_resources": [
+
{
+
"resources": ["index.js"],
+
"matches": ["https://*.discord.com/*"]
+
}
+
]
}
+12 -10
packages/browser/manifestv2.json
···
"name": "moonlight",
"description": "Yet another Discord mod",
"version": "1.1.0",
-
"content_scripts": [
-
{
-
"js": ["index.js"],
-
"matches": ["https://*.discord.com/*"],
-
"run_at": "document_start",
-
"world": "MAIN"
-
}
-
],
"permissions": [
"webRequest",
"webRequestBlocking",
-
"https://moonlight-mod.github.io/*",
+
"scripting",
+
"webNavigation",
+
"https://*.discord.com/assets/*.js",
"https://*.discord.com/*"
],
"background": {
"scripts": ["background.js"]
-
}
+
},
+
"content_scripts": [
+
{
+
"js": ["index.js"],
+
"matches": ["https://*.discord.com/*"],
+
"run_at": "document_start",
+
"world": "MAIN"
+
}
+
]
}
+1 -1
packages/browser/modifyResponseHeaders.json
···
[
{
"id": 1,
-
"priority": 1,
+
"priority": 2,
"action": {
"type": "modifyHeaders",
"responseHeaders": [
+99
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"]
+
);
+
+
chrome.webRequest.onHeadersReceived.addListener(
+
(details) => {
+
return {
+
responseHeaders: details.responseHeaders.filter(
+
(header) => header.name.toLowerCase() !== "content-security-policy"
+
)
+
};
+
},
+
{ urls: ["https://*.discord.com/*"] },
+
["blocking", "responseHeaders"]
+
);
+112 -10
packages/browser/src/background.js
···
-
// This is so tiny that I don't need to esbuild it
+
/* 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);
-
// eslint-disable-next-line no-undef
-
chrome.webRequest.onHeadersReceived.addListener(
-
(details) => ({
-
responseHeaders: details.responseHeaders.filter(
-
(header) => header.name.toLowerCase() !== "content-security-policy"
-
)
-
}),
-
{ urls: ["https://*.discord.com/*"] },
-
["blocking", "responseHeaders"]
+
console.log("Running moonlight script");
+
try {
+
await chrome.scripting.executeScript({
+
target: { tabId: details.tabId },
+
world: "MAIN",
+
files: ["index.js"]
+
});
+
} catch (e) {
+
console.log(e);
+
}
+
+
console.log("Initializing moonlight");
+
try {
+
await chrome.scripting.executeScript({
+
target: { tabId: details.tabId },
+
world: "MAIN",
+
func: async () => {
+
try {
+
await window._moonlightBrowserInit();
+
} catch (e) {
+
console.log(e);
+
}
+
}
+
});
+
} catch (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");
+
try {
+
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"]
+
}
);
+3 -6
packages/browser/src/index.ts
···
import { getExtensions } from "@moonlight-mod/core/extension";
import { loadExtensions } from "@moonlight-mod/core/extension/loader";
import { MoonlightBrowserFS, MoonlightNode } from "@moonlight-mod/types";
-
import { IndexedDB } from "@zenfs/dom";
import { configure } from "@zenfs/core";
import * as fs from "@zenfs/core/promises";
-
// Mostly copy pasted from node-preload, FIXME
-
// TODO: is this safe an in IIFE?
-
(async () => {
+
window._moonlightBrowserInit = async () => {
// Set up a virtual filesystem with IndexedDB
await configure({
mounts: {
···
});
// This is set by web-preload for us
-
await window._moonlightLoad();
-
})();
+
await window._moonlightBrowserLoad();
+
};
+4 -1
packages/browser/tsconfig.json
···
{
-
"extends": "../../tsconfig.json"
+
"extends": "../../tsconfig.json",
+
"compilerOptions": {
+
"module": "ES2022"
+
}
}
+9 -7
packages/core/src/extension.ts
···
}
const fs = getFS();
-
ret.push(
-
...(await loadDetectedExtensions(
-
fs,
-
"/extensions",
-
ExtensionLoadSource.Normal
-
))
-
);
+
if (await fs.exists("/extensions")) {
+
ret.push(
+
...(await loadDetectedExtensions(
+
fs,
+
"/extensions",
+
ExtensionLoadSource.Normal
+
))
+
);
+
}
return ret;
}
+2 -1
packages/types/src/index.ts
···
var moonlightNode: MoonlightNode;
var moonlight: MoonlightWeb;
-
var _moonlightLoad: () => Promise<void>;
+
var _moonlightBrowserInit: () => Promise<void>;
+
var _moonlightBrowserLoad: () => Promise<void>;
var _moonlightBrowserFS: MoonlightBrowserFS | undefined;
}
+1 -1
packages/web-preload/src/index.ts
···
if (MOONLIGHT_ENV === "web-preload") {
load();
} else {
-
window._moonlightLoad = load;
+
window._moonlightBrowserLoad = load;
}