From e700ab1e65c02e5100bf06ba4ec80ff022f3024a Mon Sep 17 00:00:00 2001 From: Madeline <46743919+MaddyUnderStars@users.noreply.github.com> Date: Mon, 26 Sep 2022 20:33:57 +1000 Subject: Add generate:client script --- .gitignore | 3 +- .vscode/launch.json | 11 +++- package.json | 3 +- scripts/client.js | 125 ++++++++++++++++++++++++++++++++++++++ src/api/middlewares/TestClient.ts | 9 +++ src/gateway/events/Close.ts | 2 +- 6 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 scripts/client.js diff --git a/.gitignore b/.gitignore index 829ab221..c7f0d81b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,10 @@ node_modules database.db tsconfig.tsbuildinfo files/ +assets/cache .env config.json .vscode/settings.json -build +build \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 552ce0b6..86eb202e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,10 +4,19 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Launch current file", + "program": "${relativeFile}", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "node" + }, { "type": "node", "request": "launch", - "name": "Launch Program", + "name": "Bundle", "skipFiles": [ "/**" ], diff --git a/package.json b/package.json index b3536b9e..57f4600b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "start": "node dist/bundle/start.js", "build": "tsc -p .", "generate:rights": "node scripts/rights.js", - "generate:schema": "node scripts/schema.js" + "generate:schema": "node scripts/schema.js", + "generate:client": "node scripts/client.js" }, "main": "dist/bundle/index.js", "types": "src/bundle/index.ts", diff --git a/scripts/client.js b/scripts/client.js new file mode 100644 index 00000000..e73bc7ee --- /dev/null +++ b/scripts/client.js @@ -0,0 +1,125 @@ +const path = require("path"); +const fetch = require("node-fetch"); +const fs = require("fs/promises"); +const { existsSync } = require("fs"); + +const CACHE_PATH = path.join(__dirname, "..", "assets", "cache"); +const BASE_URL = "https://discord.com"; + +// Manual for now +const INDEX_SCRIPTS = [ + "83ace7450e110d16319e", // 50 + "e02290aaa8dac5d195c2", // 1 + "4f3b3c576b879a5f75d1", // 0? + "699456246fdfe7589855", // ~4500. +]; + +const doPatch = (content) => { + //remove nitro references + content = content.replace(/Discord Nitro/g, "Fosscord Premium"); + content = content.replace(/"Nitro"/g, "\"Premium\""); + content = content.replace(/Nitro /g, "Premium "); + content = content.replace(/ Nitro/g, " Premium"); + content = content.replace(/\[Nitro\]/g, "[Premium]"); + content = content.replace(/\*Nitro\*/g, "*Premium*"); + content = content.replace(/\"Nitro \. /g, "\"Premium. "); + + //remove discord references + content = content.replace(/ Discord /g, " Fosscord "); + content = content.replace(/Discord /g, "Fosscord "); + content = content.replace(/ Discord/g, " Fosscord"); + content = content.replace(/Discord Premium/g, "Fosscord Premium"); + content = content.replace(/Discord Nitro/g, "Fosscord Premium"); + content = content.replace(/Discord's/g, "Fosscord's"); + //content = content.replace(/DiscordTag/g, "FosscordTag"); + content = content.replace(/\*Discord\*/g, "*Fosscord*"); + + //server -> guild + content = content.replace(/"Server"/g, "\"Guild\""); + content.replaceAll("server.\"", "guild.\""); + content.replaceAll(" server ", " guild "); + content.replaceAll(" Server ", " Guild "); + content.replaceAll("\"Server", "\"Guild"); + + // //change some vars + // content = content.replace('dsn: "https://fa97a90475514c03a42f80cd36d147c4@sentry.io/140984"', "dsn: (/true/.test(localStorage.sentryOptIn)?'https://6bad92b0175d41a18a037a73d0cff282@sentry.thearcanebrony.net/12':'')"); + // content = content.replace('t.DSN = "https://fa97a90475514c03a42f80cd36d147c4@sentry.io/140984"', "t.DSN = (/true/.test(localStorage.sentryOptIn)?'https://6bad92b0175d41a18a037a73d0cff282@sentry.thearcanebrony.net/12':'')"); + // content = content.replace('--brand-experiment: hsl(235, calc(var(--saturation-factor, 1) * 85.6%), 64.7%);', '--brand-experiment: hsl(var(--brand-hue), calc(var(--saturation-factor, 1) * 85.6%), 50%);'); + // content = content.replaceAll(/--brand-experiment-(\d{1,4}): hsl\(235/g, '--brand-experiment-\$1: hsl(var(--brand-hue)'); + + //logos + // content = content.replace(/d: "M23\.0212.*/, `d: "${icons.get("homeIcon.path")!.toString()}"`); + // content = content.replace('width: n, height: o, viewBox: "0 0 28 20"', 'width: 48, height: 48, viewBox: "0 0 48 48"'); + + //save some time on load resolving asset urls... + content = content.replaceAll('e.exports = n.p + "', 'e.exports = "/assets/'); + content = content.replaceAll('e.exports = r.p + "', 'e.exports = "/assets/'); + + return content; +}; + +const processFile = async (name) => { + const res = await fetch(`${BASE_URL}/assets/${name}.js`); + let text = await res.text(); + + text = doPatch(text); + + await fs.writeFile(path.join(CACHE_PATH, `${name}.js`), text); + + return [...new Set(text.match((/[A-Fa-f0-9]{20}/g)))]; +}; + +(async () => { + const start = Date.now(); + + // console.log("Deleting previous cache"); + // await fs.rm(CACHE_PATH, { recursive: true }); + // await fs.mkdir(CACHE_PATH); + + const assets = []; + + while (INDEX_SCRIPTS.length > 0) { + const asset = INDEX_SCRIPTS.shift(); + + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + process.stdout.write(`Scraping asset ${asset}. Remaining: ${INDEX_SCRIPTS.length}`); + + const newAssets = await processFile(asset); + assets.push(...newAssets); + } + + process.stdout.moveCursor(0, 1); + + let rates = []; + let lastFinished = Date.now(); + let previousFinish = Date.now(); + + for (var i = 0; i < assets.length; i++) { + const asset = assets[i]; + + if (existsSync(path.join(CACHE_PATH, `${asset}.js`))) { + continue; + } + + while (rates.length > 20) rates.shift(); + const averageRate = rates.length ? rates.reduce((prev, curr) => prev + curr) / rates.length : 1; + const finishTime = (averageRate * (assets.length - i)); + + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + process.stdout.write( + `Caching asset ${asset}. ` + + `${i}/${assets.length - 1} = ${Math.floor((i / (assets.length - 1)) * 100)}% ` + + `Finish at: ${new Date(Date.now() + finishTime).toLocaleTimeString()}` + ); + + await processFile(asset); + + lastFinished = Date.now(); + rates.push(lastFinished - previousFinish); + previousFinish = lastFinished; + } + + console.log(`\nDone`); +})(); \ No newline at end of file diff --git a/src/api/middlewares/TestClient.ts b/src/api/middlewares/TestClient.ts index 765059c7..e68abf98 100644 --- a/src/api/middlewares/TestClient.ts +++ b/src/api/middlewares/TestClient.ts @@ -7,6 +7,8 @@ import { Config } from "@fosscord/util"; const ASSET_FOLDER_PATH = path.join(__dirname, "..", "..", "..", "assets"); +let hasWarnedAboutCache = false; + export default function TestClient(app: Application) { const agent = new ProxyAgent(); const assetCache = new Map(); @@ -44,8 +46,15 @@ export default function TestClient(app: Application) { app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "public"))); + app.use("/assets", express.static(path.join(ASSET_FOLDER_PATH, "cache"))); app.get("/assets/:file", async (req: Request, res: Response) => { + if (!hasWarnedAboutCache) { + hasWarnedAboutCache = true; + if (req.params.file.includes(".js")) + console.warn(`[TestClient] Cache miss for file ${req.params.file}! Use 'npm run generate:client' to cache and patch.`); + } + delete req.headers.host; var response: FetchResponse; var buffer: Buffer; diff --git a/src/gateway/events/Close.ts b/src/gateway/events/Close.ts index 40d9a6f7..82d16234 100644 --- a/src/gateway/events/Close.ts +++ b/src/gateway/events/Close.ts @@ -9,7 +9,7 @@ import { } from "@fosscord/util"; export async function Close(this: WebSocket, code: number, reason: string) { - console.log("[WebSocket] closed", code, reason); + console.log("[WebSocket] closed", code, reason.toString()); if (this.heartbeatTimeout) clearTimeout(this.heartbeatTimeout); if (this.readyTimeout) clearTimeout(this.readyTimeout); this.deflate?.close(); -- cgit 1.4.1