Skip to content

Commit

Permalink
[shelter] improve bundle fetching
Browse files Browse the repository at this point in the history
this also fixes shelter failing to load when there's no internet connection right on launch
  • Loading branch information
ioj4 committed Jan 9, 2025
1 parent 87015af commit f3f2d1f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## r18
Improve shelter bundle fetching

## r17
- Make the new dashboard look nicer
- Replace useless last module time with cache hit rates
Expand Down
85 changes: 64 additions & 21 deletions branches/mod/shelter/patch.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
const electron = require("electron");
const path = require("path");
const Module = require("module");
const fs = require("original-fs"); // using electron's fs causes app.asar to be locked during host updates
const fs = require("original-fs"); // "fs" module without electron modifications
const https = require("https");
const { EOL } = require("os");

const logger = new Proxy(console, {
get: (target, key) =>
function (...args) {
//logFile?.write(`[${new Date().toISOString()}] [${key}] ${args.join(" ")}${EOL}`);
return target[key].apply(console, ["[shelter]", ...args]);
},
});
Expand All @@ -18,42 +17,63 @@ logger.log("Loading...");
// #region Bundle
const remoteUrl =
process.env.SHELTER_BUNDLE_URL || "https://raw.githubusercontent.com/uwu/shelter-builds/main/shelter.js";
const localBundle = process.env.SHELTER_DIST_PATH;
const distPath = process.env.SHELTER_DIST_PATH;

let fetchPromise; // only fetch once
let localBundle;

if (!localBundle)
fetchPromise = new Promise((resolve, reject) => {
if (distPath) {
localBundle =
fs.readFileSync(path.join(distPath, "shelter.js"), "utf8") +
`\n//# sourceMappingURL=file://${process.platform === "win32" ? "/" : ""}${path.join(distPath, "shelter.js.map")}`;
}

let remoteBundle;
let remoteBundlePromise;

const fetchRemoteBundleIfNeeded = () => {
if (localBundle || remoteBundle) return Promise.resolve();

remoteBundlePromise ??= new Promise((resolve) => {
const req = https.get(remoteUrl);

req.on("response", (res) => {
if (res.statusCode !== 200) {
remoteBundlePromise = null;
resolve();
return;
}
const chunks = [];

res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
let data = Buffer.concat(chunks).toString("utf-8");
let script = Buffer.concat(chunks).toString("utf-8");

if (!data.includes("//# sourceMappingURL=")) data += `\n//# sourceMappingURL=${remoteUrl + ".map"}`;

resolve(data);
if (!script.includes("//# sourceMappingURL=")) script += `\n//# sourceMappingURL=${remoteUrl + ".map"}`;
remoteBundle = script;
remoteBundlePromise = null;
resolve();
});
});

req.on("error", reject);
req.on("error", (e) => {
logger.error("Error fetching remote bundle:", e);
remoteBundlePromise = null;
resolve();
});

req.end();
});

const getShelterBundle = () =>
!localBundle
? fetchPromise
: Promise.resolve(
fs.readFileSync(path.join(localBundle, "shelter.js"), "utf8") +
`\n//# sourceMappingURL=file://${process.platform === "win32" ? "/" : ""}${path.join(
localBundle,
"shelter.js.map",
)}`,
);
return remoteBundlePromise;
};

fetchRemoteBundleIfNeeded();

const getShelterBundle = () => {
if (localBundle) return localBundle;
if (remoteBundle) return remoteBundle;
return `console.error("[shelter] Bundle could not be fetched in time. Aborting!");`;
};
// #endregion

// #region IPC
Expand Down Expand Up @@ -157,5 +177,28 @@ Module.prototype.require = function (path) {
}
return loadedModule;
};
// #endregion

// #region Patch BrowserWindow
const ProxiedBrowserWindow = new Proxy(electron.BrowserWindow, {
construct(target, args) {
const window = new target(...args);
const originalLoadURL = window.loadURL;
window.loadURL = async function (url) {
if (url.includes("discord.com/app")) {
await fetchRemoteBundleIfNeeded();
}
return await originalLoadURL.apply(this, arguments);
};

return window;
},
});

const electronPath = require.resolve("electron");
delete require.cache[electronPath].exports;
require.cache[electronPath].exports = {
...electron,
BrowserWindow: ProxiedBrowserWindow,
};
// #endregion

0 comments on commit f3f2d1f

Please sign in to comment.