From 80d240a80e2be8a710cf81c98ab56846cd0c2909 Mon Sep 17 00:00:00 2001 From: tsukasa <102845+tsukasa@users.noreply.github.com> Date: Sat, 15 Apr 2023 03:21:50 +0200 Subject: [PATCH] Startup and Preload Changes - Reworked startup so both betterdiscord.js and betterdiscord.asar can be loaded from the local ./dist/ extension folder. This makes it easier for users to quickly override the VFS asar file. NOTE: The load order is... 1. Local betterdiscord.js 2. Local betterdiscord.asar 3. VFS betterdiscord.asar - Renamed constant BD_CONFIG_PLUGINS to fit in with the rest of the FilePath constants. - Added try/catch for backend IPC fetch handler. - Added localizations for the extension options page (en/de). - Added missing filesystem definitions to the bdPreload object. --- _locales/de/messages.json | 23 +++++ _locales/en/messages.json | 23 +++++ assets/chrome/options.html | 14 +-- assets/chrome/options.js | 38 ++++++++- backend/src/index.js | 25 +++--- common/constants.js | 2 +- dist/backend.js | 21 +++-- dist/frontend.js | 114 ++++++++++++++++++------- frontend/src/modules/bdAsarUpdater.js | 4 +- frontend/src/modules/bdPreload.js | 7 +- frontend/src/modules/fs.js | 4 +- frontend/src/modules/https.js | 4 +- frontend/src/modules/runtimeInfo.js | 23 ++--- frontend/src/modules/runtimeOptions.js | 2 +- frontend/src/modules/startup.js | 66 +++++++++++--- manifest.json | 8 +- 16 files changed, 280 insertions(+), 98 deletions(-) create mode 100644 _locales/de/messages.json create mode 100644 _locales/en/messages.json diff --git a/_locales/de/messages.json b/_locales/de/messages.json new file mode 100644 index 0000000..a02b1ff --- /dev/null +++ b/_locales/de/messages.json @@ -0,0 +1,23 @@ +{ + "extName": { + "message": "BDBrowser" + }, + "extDesc": { + "message": "Erlaubt das Laden von BetterDiscord im Web Client. Manche Plugins funktionieren ggf. nicht." + }, + "titlePersistentOptions": { + "message": "Dauerhafte Optionen" + }, + "titleResetOnReloadOptions": { + "message": "Einmalige Optionen" + }, + "disableBdRenderer": { + "message": "BetterDiscord Renderer nicht laden" + }, + "disableBdPluginsOnReload": { + "message": "Beim Laden alle Plugins deaktivieren" + }, + "deleteBdRendererOnReload": { + "message": "Beim Laden Asar aus VFS löschen" + } +} diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..ec3197b --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,23 @@ +{ + "extName": { + "message": "BDBrowser" + }, + "extDesc": { + "message": "Allows you to use BetterDiscord on the web client. Some plugins might not be working correctly." + }, + "titlePersistentOptions": { + "message": "Persistent Options" + }, + "titleResetOnReloadOptions": { + "message": "Reset on Reload Options" + }, + "disableBdRenderer": { + "message": "Do not load BetterDiscord Renderer" + }, + "disableBdPluginsOnReload": { + "message": "Disable all Plugins on Reload" + }, + "deleteBdRendererOnReload": { + "message": "Delete Asar from VFS on Reload" + } +} diff --git a/assets/chrome/options.html b/assets/chrome/options.html index eb1c80f..383ba5b 100644 --- a/assets/chrome/options.html +++ b/assets/chrome/options.html @@ -8,25 +8,25 @@
-

- Persistent Options +

+ #titlePersistentOptions

- +

-

- Reset on Reload Options +

+ #titleResetOnReloadOptions

- +

- +

diff --git a/assets/chrome/options.js b/assets/chrome/options.js index e7bada3..d0b6efa 100644 --- a/assets/chrome/options.js +++ b/assets/chrome/options.js @@ -30,7 +30,37 @@ const restoreOptions = () => { ); }; -document.addEventListener('DOMContentLoaded', restoreOptions); -document.getElementById('disableBdRenderer').addEventListener('change', saveOptions); -document.getElementById('disableBdPluginsOnReload').addEventListener('change', saveOptions); -document.getElementById('deleteBdRendererOnReload').addEventListener('change', saveOptions); +/** + * Loads the i18n messages for the options page. + * The i18n messages are loaded from the _locales folder. + */ +const loadI18n = () => { + let elements = document.querySelectorAll("[i18n]"); + + elements.forEach(element => { + const i18nElement = element.getAttribute("i18n"); + const i18nMessage = chrome.i18n.getMessage(i18nElement); + + if (i18nMessage) { + element.innerText = i18nMessage; + } + }); +} + +/** + * Operations to perform once options page has loaded. + */ +const onContentLoaded = () => { + loadI18n(); + restoreOptions(); +} + +const initialize = () => { + document.addEventListener("DOMContentLoaded", onContentLoaded); + + document.getElementById("disableBdRenderer").addEventListener("change", saveOptions); + document.getElementById("disableBdPluginsOnReload").addEventListener("change", saveOptions); + document.getElementById("deleteBdRendererOnReload").addEventListener("change", saveOptions); +} + +initialize(); diff --git a/backend/src/index.js b/backend/src/index.js index f457be0..5a03a7d 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -124,18 +124,23 @@ function registerEvents() { options: data.options } }, (response) => { - if (response.error) { - if(!data.url.startsWith(chrome.runtime.getURL(""))) - console.error("BdBrowser Backend MAKE_REQUESTS failed:", data.url, response.error); + try { + if (response.error) { + if(!data.url.startsWith(chrome.runtime.getURL(""))) + console.error("BdBrowser Backend MAKE_REQUESTS failed:", data.url, response.error); + ipcMain.reply(event, undefined); + } + else + { + // Response body comes in as a normal array, so requires + // another round of casting into Uint8Array for the buffer. + response.body = new Uint8Array(response.body).buffer; + ipcMain.reply(event, response); + } + } catch(error) { + Logger.error("Backend", "MAKE_REQUESTS failed:", error, data.url, response); ipcMain.reply(event, undefined); } - else - { - // Response body comes in as a normal array, so requires - // another round of casting into Uint8Array for the buffer. - response.body = new Uint8Array(response.body).buffer; - ipcMain.reply(event, response); - } } ); }); diff --git a/common/constants.js b/common/constants.js index d24567e..02522d0 100644 --- a/common/constants.js +++ b/common/constants.js @@ -11,7 +11,7 @@ export const IPCEvents = { export const FilePaths = { BD_ASAR_PATH: "AppData/BetterDiscord/data/betterdiscord.asar", BD_ASAR_VERSION_PATH: "AppData/BetterDiscord/data/bd-asar-version.txt", - BD_CONFIG_PLUGINS: "AppData/BetterDiscord/data/&1/plugins.json" + BD_CONFIG_PLUGINS_PATH: "AppData/BetterDiscord/data/&1/plugins.json" } export default { diff --git a/dist/backend.js b/dist/backend.js index d79b95d..9d8464b 100644 --- a/dist/backend.js +++ b/dist/backend.js @@ -15,7 +15,7 @@ const IPCEvents = { const FilePaths = { BD_ASAR_PATH: "AppData/BetterDiscord/data/betterdiscord.asar", BD_ASAR_VERSION_PATH: "AppData/BetterDiscord/data/bd-asar-version.txt", - BD_CONFIG_PLUGINS: "AppData/BetterDiscord/data/&1/plugins.json" + BD_CONFIG_PLUGINS_PATH: "AppData/BetterDiscord/data/&1/plugins.json" }; /* harmony default export */ const constants = ({ IPCEvents, @@ -289,14 +289,19 @@ function registerEvents() { options: data.options } }, response => { - if (response.error) { - if (!data.url.startsWith(chrome.runtime.getURL(""))) console.error("BdBrowser Backend MAKE_REQUESTS failed:", data.url, response.error); + try { + if (response.error) { + if (!data.url.startsWith(chrome.runtime.getURL(""))) console.error("BdBrowser Backend MAKE_REQUESTS failed:", data.url, response.error); + ipcMain.reply(event, undefined); + } else { + // Response body comes in as a normal array, so requires + // another round of casting into Uint8Array for the buffer. + response.body = new Uint8Array(response.body).buffer; + ipcMain.reply(event, response); + } + } catch (error) { + Logger.error("Backend", "MAKE_REQUESTS failed:", error, data.url, response); ipcMain.reply(event, undefined); - } else { - // Response body comes in as a normal array, so requires - // another round of casting into Uint8Array for the buffer. - response.body = new Uint8Array(response.body).buffer; - ipcMain.reply(event, response); } }); }); diff --git a/dist/frontend.js b/dist/frontend.js index 7e3370d..c676084 100644 --- a/dist/frontend.js +++ b/dist/frontend.js @@ -21,7 +21,7 @@ const IPCEvents = { const FilePaths = { BD_ASAR_PATH: "AppData/BetterDiscord/data/betterdiscord.asar", BD_ASAR_VERSION_PATH: "AppData/BetterDiscord/data/bd-asar-version.txt", - BD_CONFIG_PLUGINS: "AppData/BetterDiscord/data/&1/plugins.json" + BD_CONFIG_PLUGINS_PATH: "AppData/BetterDiscord/data/&1/plugins.json" }; /* unused harmony default export */ var __WEBPACK_DEFAULT_EXPORT__ = ({ IPCEvents, @@ -277,7 +277,7 @@ class BdAsarUpdater { * Gets the version of BetterDiscord's asar according to the version file in the VFS. * @returns {string} - Version number or `0.0.0` if no value is set yet. */ - static getLocalBetterDiscordAsarVersion() { + static getVfsBetterDiscordAsarVersion() { if (_fs__WEBPACK_IMPORTED_MODULE_0__/* ["default"].existsSync */ .ZP.existsSync(common_constants__WEBPACK_IMPORTED_MODULE_2__/* .FilePaths.BD_ASAR_VERSION_PATH */ .F_.BD_ASAR_VERSION_PATH)) return _fs__WEBPACK_IMPORTED_MODULE_0__/* ["default"].readFileSync */ .ZP.readFileSync(common_constants__WEBPACK_IMPORTED_MODULE_2__/* .FilePaths.BD_ASAR_VERSION_PATH */ .F_.BD_ASAR_VERSION_PATH).toString();else return "0.0.0"; } @@ -323,7 +323,7 @@ class BdAsarUpdater { }); const data = await resp.json(); const remoteVersion = data["tag_name"].startsWith("v") ? data["tag_name"].slice(1) : data["tag_name"]; - const hasUpdate = remoteVersion > this.getLocalBetterDiscordAsarVersion(); + const hasUpdate = remoteVersion > this.getVfsBetterDiscordAsarVersion(); common_logger__WEBPACK_IMPORTED_MODULE_3__/* ["default"].log */ .Z.log(LOGGER_SECTION, `Latest stable BetterDiscord version is ${remoteVersion}.`); return { data, @@ -393,7 +393,12 @@ class BdAsarUpdater { deleteDirectory: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].rmdirSync */ .ZP.rmdirSync, exists: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].existsSync */ .ZP.existsSync, getRealPath: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].realpathSync */ .ZP.realpathSync, - rename: () => {}, + rename: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].renameSync */ .ZP.renameSync, + renameSync: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].renameSync */ .ZP.renameSync, + rm: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].rmSync */ .ZP.rmSync, + rmSync: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].rmSync */ .ZP.rmSync, + unlinkSync: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].unlinkSync */ .ZP.unlinkSync, + createWriteStream: () => {}, watch: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].watch */ .ZP.watch, getStats: _fs__WEBPACK_IMPORTED_MODULE_1__/* ["default"].statSync */ .ZP.statSync }, @@ -2594,7 +2599,7 @@ function request(url, options, callback) { value: data.type }); Object.defineProperty(res, "url", { - value: "" + value: data.url }); emitter.emit("end", res); }).catch(error => { @@ -3275,7 +3280,7 @@ require_require.resolve = path => { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ZP": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -/* unused harmony exports addExtensionVersionInfo, getFormattedBdRendererSourceString, getRuntimeInfo, parseBetterDiscordVersion, setBdLoadedFromAsar */ +/* unused harmony exports addExtensionVersionInfo, getFormattedBdRendererSourceString, getRuntimeInfo, parseBetterDiscordVersion, setBdRendererSource */ /* harmony import */ var common_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(65); /* harmony import */ var _bdAsarUpdater__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(883); /* harmony import */ var _ipc__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(523); @@ -3287,11 +3292,12 @@ let runtimeInfo; let activeVersionObserver; (async () => { const manifestInfo = await _ipc__WEBPACK_IMPORTED_MODULE_2__/* ["default"].sendAwait */ .Z.sendAwait(common_constants__WEBPACK_IMPORTED_MODULE_0__/* .IPCEvents.GET_MANIFEST_INFO */ .AY.GET_MANIFEST_INFO); - const bdVersion = _bdAsarUpdater__WEBPACK_IMPORTED_MODULE_1__/* ["default"].getLocalBetterDiscordAsarVersion */ .Z.getLocalBetterDiscordAsarVersion(); + const bdVersion = _bdAsarUpdater__WEBPACK_IMPORTED_MODULE_1__/* ["default"].getVfsBetterDiscordAsarVersion */ .Z.getVfsBetterDiscordAsarVersion(); runtimeInfo = { manifest: manifestInfo, bdVersion: bdVersion, - hasLoadedBdFromAsar: true + rendererSourceName: "Unknown", + isLocalFile: false }; })(); @@ -3319,7 +3325,7 @@ function addExtensionVersionInfo() { }; const bdbVersionInfo = addInfoSpanElement(idSpanVersion, `${runtimeInfo.manifest.name} ${runtimeInfo.manifest.version}`); discordBuildInfo.after(bdbVersionInfo); - const bdbRendererInfo = addInfoSpanElement(idSpanRenderer, getFormattedBdRendererSourceString(), [runtimeInfo.hasLoadedBdFromAsar ? "" : "color: var(--text-warning);"]); + const bdbRendererInfo = addInfoSpanElement(idSpanRenderer, getFormattedBdRendererSourceString(), [runtimeInfo.isLocalFile ? "color: var(--text-warning);" : ""]); bdbVersionInfo.after(bdbRendererInfo); }); if (!activeVersionObserver) { @@ -3337,7 +3343,8 @@ function addExtensionVersionInfo() { */ function getFormattedBdRendererSourceString() { const version = runtimeInfo.bdVersion === UNKNOWN_VERSION ? UNKNOWN_VERSION : "v" + runtimeInfo.bdVersion; - if (runtimeInfo.hasLoadedBdFromAsar) return `betterdiscord.asar (${version}, VFS)`;else return `betterdiscord.js (${version}, local)`; + const hostFs = runtimeInfo.isLocalFile ? "local" : "VFS"; + return `${runtimeInfo.rendererSourceName} (${version}, ${hostFs})`; } /** @@ -3369,17 +3376,19 @@ function parseBetterDiscordVersion(bdBodyScript) { /** * Sets whether the BetterDiscord renderer has been loaded from an asar file within the VFS. - * @param {boolean} isLoadedFromAsar + * @param {String} sourceName + * @param {Boolean} isLocalFile */ -function setBdLoadedFromAsar(isLoadedFromAsar) { - runtimeInfo.hasLoadedBdFromAsar = isLoadedFromAsar; +function setBdRendererSource(sourceName, isLocalFile) { + runtimeInfo.rendererSourceName = sourceName; + runtimeInfo.isLocalFile = isLocalFile; } /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ addExtensionVersionInfo, getFormattedBdRendererSourceString, getRuntimeInfo, parseBetterDiscordVersion, - setBdLoadedFromAsar + setBdRendererSource }); /***/ }), @@ -3440,7 +3449,7 @@ class RuntimeOptions { */ static async disableAllBetterDiscordPlugins() { if (!this.getOption("disableBdPluginsOnReload")) return; - const pluginConfigPath = common_constants__WEBPACK_IMPORTED_MODULE_0__/* .FilePaths.BD_CONFIG_PLUGINS.replace */ .F_.BD_CONFIG_PLUGINS.replace("&1", _discordnative__WEBPACK_IMPORTED_MODULE_1__/* .app.getReleaseChannel */ .l.getReleaseChannel()); + const pluginConfigPath = common_constants__WEBPACK_IMPORTED_MODULE_0__/* .FilePaths.BD_CONFIG_PLUGINS_PATH.replace */ .F_.BD_CONFIG_PLUGINS_PATH.replace("&1", _discordnative__WEBPACK_IMPORTED_MODULE_1__/* .app.getReleaseChannel */ .l.getReleaseChannel()); if (!_fs__WEBPACK_IMPORTED_MODULE_2__/* ["default"].existsSync */ .ZP.existsSync(pluginConfigPath)) return; const rawFileData = _fs__WEBPACK_IMPORTED_MODULE_2__/* ["default"].readFileSync */ .ZP.readFileSync(pluginConfigPath); let plugins = JSON.parse(new TextDecoder().decode(rawFileData)); @@ -3515,25 +3524,63 @@ async function checkAndDownloadBetterDiscordAsar() { * @returns {Promise} scriptBody - A string containing the BetterDiscord renderer source to eval. */ async function getBdRendererScript() { - let bdBody; - const localRendererUrl = await _ipc__WEBPACK_IMPORTED_MODULE_8__/* ["default"].sendAwait */ .Z.sendAwait(common_constants__WEBPACK_IMPORTED_MODULE_0__/* .IPCEvents.GET_RESOURCE_URL */ .AY.GET_RESOURCE_URL, { - url: "dist/betterdiscord.js" - }); - const localRendererResp = await _ipc__WEBPACK_IMPORTED_MODULE_8__/* ["default"].sendAwait */ .Z.sendAwait(common_constants__WEBPACK_IMPORTED_MODULE_0__/* .IPCEvents.MAKE_REQUESTS */ .AY.MAKE_REQUESTS, { - url: localRendererUrl - }); - if (!localRendererResp) { - common_logger__WEBPACK_IMPORTED_MODULE_13__/* ["default"].info */ .Z.info("Frontend", "Reading renderer.js from betterdiscord.asar..."); - bdBody = new _asar__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z(_bdAsarUpdater__WEBPACK_IMPORTED_MODULE_2__/* ["default"].asarFile.buffer */ .Z.asarFile.buffer).get("renderer.js"); - _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].setBdLoadedFromAsar */ .ZP.setBdLoadedFromAsar(true); - } else { + /** + * Attempts to get the contents of a web_accessible_resource of the extension. + * @param url + * @returns {Promise} + */ + const tryGetLocalFile = async url => { + const localRendererUrl = await _ipc__WEBPACK_IMPORTED_MODULE_8__/* ["default"].sendAwait */ .Z.sendAwait(common_constants__WEBPACK_IMPORTED_MODULE_0__/* .IPCEvents.GET_RESOURCE_URL */ .AY.GET_RESOURCE_URL, { + url: url + }); + return await _ipc__WEBPACK_IMPORTED_MODULE_8__/* ["default"].sendAwait */ .Z.sendAwait(common_constants__WEBPACK_IMPORTED_MODULE_0__/* .IPCEvents.MAKE_REQUESTS */ .AY.MAKE_REQUESTS, { + url: localRendererUrl + }); + }; + + /** + * Tries to load the betterdiscord.js from the ./dist folder. + * @returns {Promise} + */ + const tryGetLocalBetterDiscordJs = async () => { + const localFileContents = await tryGetLocalFile("dist/betterdiscord.js"); + if (!localFileContents) return; common_logger__WEBPACK_IMPORTED_MODULE_13__/* ["default"].info */ .Z.info("Frontend", "Reading betterdiscord.js from local extension folder..."); - bdBody = localRendererResp.body; - _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].setBdLoadedFromAsar */ .ZP.setBdLoadedFromAsar(false); - } - const scriptBody = new TextDecoder().decode(bdBody); - _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].parseBetterDiscordVersion */ .ZP.parseBetterDiscordVersion(scriptBody); - return scriptBody; + _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].setBdRendererSource */ .ZP.setBdRendererSource("betterdiscord.js", true); + return localFileContents.body; + }; + + /** + * Tries to load the betterdiscord.asar from the ./dist folder. + * @returns {Promise} + */ + const tryGetLocalBetterDiscordAsar = async () => { + const localFileContents = await tryGetLocalFile("dist/betterdiscord.asar"); + if (!localFileContents) return; + common_logger__WEBPACK_IMPORTED_MODULE_13__/* ["default"].info */ .Z.info("Frontend", "Reading betterdiscord.asar from local extension folder..."); + _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].setBdRendererSource */ .ZP.setBdRendererSource("betterdiscord.asar", true); + return new _asar__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z(localFileContents.body).get("renderer.js"); + }; + + /** + * Tries to load the betterdiscord.asar from the VFS. + * @returns {undefined|ArrayBuffer} + */ + const tryGetVfsBetterDiscordAsar = () => { + common_logger__WEBPACK_IMPORTED_MODULE_13__/* ["default"].info */ .Z.info("Frontend", "Reading betterdiscord.asar in the VFS..."); + _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].setBdRendererSource */ .ZP.setBdRendererSource("betterdiscord.asar", false); + return new _asar__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z(_bdAsarUpdater__WEBPACK_IMPORTED_MODULE_2__/* ["default"].asarFile.buffer */ .Z.asarFile.buffer).get("renderer.js"); + }; + + /** + * Gets the BetterDiscord renderer script body. + * @returns {Promise} + */ + const getRenderer = async () => { + return (await tryGetLocalBetterDiscordJs()) || (await tryGetLocalBetterDiscordAsar()) || tryGetVfsBetterDiscordAsar(); + }; + const bdBodyBuffer = await getRenderer(); + return new TextDecoder().decode(bdBodyBuffer); } /** @@ -3546,6 +3593,7 @@ async function loadBetterDiscord() { const connectionOpenEvent = "CONNECTION_OPEN"; const bdScriptBody = await getBdRendererScript(); if (!bdScriptBody) return false; + _runtimeInfo__WEBPACK_IMPORTED_MODULE_11__/* ["default"].parseBetterDiscordVersion */ .ZP.parseBetterDiscordVersion(bdScriptBody); const callback = async () => { _discordmodules__WEBPACK_IMPORTED_MODULE_5__/* ["default"].Dispatcher.unsubscribe */ .Z.Dispatcher.unsubscribe(connectionOpenEvent, callback); try { diff --git a/frontend/src/modules/bdAsarUpdater.js b/frontend/src/modules/bdAsarUpdater.js index 2a04a0e..26cb742 100644 --- a/frontend/src/modules/bdAsarUpdater.js +++ b/frontend/src/modules/bdAsarUpdater.js @@ -11,7 +11,7 @@ export default class BdAsarUpdater { * Gets the version of BetterDiscord's asar according to the version file in the VFS. * @returns {string} - Version number or `0.0.0` if no value is set yet. */ - static getLocalBetterDiscordAsarVersion() { + static getVfsBetterDiscordAsarVersion() { if(fs.existsSync(FilePaths.BD_ASAR_VERSION_PATH)) return fs.readFileSync(FilePaths.BD_ASAR_VERSION_PATH).toString(); else @@ -65,7 +65,7 @@ export default class BdAsarUpdater { const data = await resp.json(); const remoteVersion = data["tag_name"].startsWith("v") ? data["tag_name"].slice(1) : data["tag_name"]; - const hasUpdate = remoteVersion > this.getLocalBetterDiscordAsarVersion(); + const hasUpdate = remoteVersion > this.getVfsBetterDiscordAsarVersion(); Logger.log(LOGGER_SECTION, `Latest stable BetterDiscord version is ${remoteVersion}.`); diff --git a/frontend/src/modules/bdPreload.js b/frontend/src/modules/bdPreload.js index 32bbf5c..ffbda7c 100644 --- a/frontend/src/modules/bdPreload.js +++ b/frontend/src/modules/bdPreload.js @@ -13,7 +13,12 @@ export default { deleteDirectory: fs.rmdirSync, exists: fs.existsSync, getRealPath: fs.realpathSync, - rename: () => {}, + rename: fs.renameSync, + renameSync: fs.renameSync, + rm: fs.rmSync, + rmSync: fs.rmSync, + unlinkSync: fs.unlinkSync, + createWriteStream: () => {}, watch: fs.watch, getStats: fs.statSync }, diff --git a/frontend/src/modules/fs.js b/frontend/src/modules/fs.js index 361a415..729cba8 100644 --- a/frontend/src/modules/fs.js +++ b/frontend/src/modules/fs.js @@ -263,7 +263,7 @@ function hasBdBrowserFiles() { */ function hasBeenMigrated() { let wasMigrated = LocalStorage.getItem(BD_FILES_MIGRATED_KEY); - return (wasMigrated === true); + return wasMigrated === true; } /** @@ -1287,4 +1287,4 @@ const fs = { writeFileSync } -export default fs; \ No newline at end of file +export default fs; diff --git a/frontend/src/modules/https.js b/frontend/src/modules/https.js index 3924e56..e2415af 100644 --- a/frontend/src/modules/https.js +++ b/frontend/src/modules/https.js @@ -34,7 +34,7 @@ export function request(url, options, callback) { Object.defineProperty(res, "statusCode", { value: data.status }); Object.defineProperty(res, "statusText", { value: data.statusText }); Object.defineProperty(res, "type", { value: data.type }); - Object.defineProperty(res, "url", { value: "" }); + Object.defineProperty(res, "url", { value: data.url }); emitter.emit("end", res); }) .catch(error => { @@ -62,4 +62,4 @@ https.get = request; https.createServer = createServer; https.request = request; -export default https; \ No newline at end of file +export default https; diff --git a/frontend/src/modules/runtimeInfo.js b/frontend/src/modules/runtimeInfo.js index d08d7c3..242ac22 100644 --- a/frontend/src/modules/runtimeInfo.js +++ b/frontend/src/modules/runtimeInfo.js @@ -9,12 +9,13 @@ let activeVersionObserver; (async () => { const manifestInfo = await ipcRenderer.sendAwait(IPCEvents.GET_MANIFEST_INFO); - const bdVersion = BdAsarUpdater.getLocalBetterDiscordAsarVersion(); + const bdVersion = BdAsarUpdater.getVfsBetterDiscordAsarVersion(); runtimeInfo = { manifest: manifestInfo, bdVersion: bdVersion, - hasLoadedBdFromAsar: true + rendererSourceName: "Unknown", + isLocalFile: false }; })(); @@ -55,7 +56,7 @@ export function addExtensionVersionInfo() { const bdbRendererInfo = addInfoSpanElement( idSpanRenderer, getFormattedBdRendererSourceString(), - [(runtimeInfo.hasLoadedBdFromAsar ? "" : "color: var(--text-warning);")] + [(runtimeInfo.isLocalFile ? "color: var(--text-warning);" : "")] ); bdbVersionInfo.after(bdbRendererInfo); }); @@ -75,11 +76,9 @@ export function addExtensionVersionInfo() { */ export function getFormattedBdRendererSourceString() { const version = (runtimeInfo.bdVersion === UNKNOWN_VERSION) ? UNKNOWN_VERSION : "v" + runtimeInfo.bdVersion; + const hostFs = runtimeInfo.isLocalFile ? "local" : "VFS"; - if (runtimeInfo.hasLoadedBdFromAsar) - return `betterdiscord.asar (${version}, VFS)`; - else - return `betterdiscord.js (${version}, local)`; + return `${runtimeInfo.rendererSourceName} (${version}, ${hostFs})`; } /** @@ -115,10 +114,12 @@ export function parseBetterDiscordVersion(bdBodyScript) { /** * Sets whether the BetterDiscord renderer has been loaded from an asar file within the VFS. - * @param {boolean} isLoadedFromAsar + * @param {String} sourceName + * @param {Boolean} isLocalFile */ -export function setBdLoadedFromAsar(isLoadedFromAsar) { - runtimeInfo.hasLoadedBdFromAsar = isLoadedFromAsar; +export function setBdRendererSource(sourceName, isLocalFile) { + runtimeInfo.rendererSourceName = sourceName; + runtimeInfo.isLocalFile = isLocalFile; } export default { @@ -126,5 +127,5 @@ export default { getFormattedBdRendererSourceString, getRuntimeInfo, parseBetterDiscordVersion, - setBdLoadedFromAsar + setBdRendererSource } diff --git a/frontend/src/modules/runtimeOptions.js b/frontend/src/modules/runtimeOptions.js index 6688d36..7445a4a 100644 --- a/frontend/src/modules/runtimeOptions.js +++ b/frontend/src/modules/runtimeOptions.js @@ -53,7 +53,7 @@ export default class RuntimeOptions { if (!this.getOption("disableBdPluginsOnReload")) return; - const pluginConfigPath = FilePaths.BD_CONFIG_PLUGINS.replace("&1", app.getReleaseChannel()); + const pluginConfigPath = FilePaths.BD_CONFIG_PLUGINS_PATH.replace("&1", app.getReleaseChannel()); if (!fs.existsSync(pluginConfigPath)) return; diff --git a/frontend/src/modules/startup.js b/frontend/src/modules/startup.js index 28392cb..d6ef53c 100644 --- a/frontend/src/modules/startup.js +++ b/frontend/src/modules/startup.js @@ -43,27 +43,65 @@ async function checkAndDownloadBetterDiscordAsar() { * @returns {Promise} scriptBody - A string containing the BetterDiscord renderer source to eval. */ async function getBdRendererScript() { - let bdBody; - const localRendererUrl = await ipcRenderer.sendAwait(IPCEvents.GET_RESOURCE_URL, {url: "dist/betterdiscord.js"}); + /** + * Attempts to get the contents of a web_accessible_resource of the extension. + * @param url + * @returns {Promise} + */ + const tryGetLocalFile = async (url) => { + const localRendererUrl = await ipcRenderer.sendAwait(IPCEvents.GET_RESOURCE_URL, {url: url}); + return await ipcRenderer.sendAwait(IPCEvents.MAKE_REQUESTS, {url: localRendererUrl}); + } - const localRendererResp = await ipcRenderer.sendAwait(IPCEvents.MAKE_REQUESTS, {url: localRendererUrl}); + /** + * Tries to load the betterdiscord.js from the ./dist folder. + * @returns {Promise} + */ + const tryGetLocalBetterDiscordJs = async () => { + const localFileContents = await tryGetLocalFile("dist/betterdiscord.js"); + if(!localFileContents) + return; - if (!localRendererResp) { - Logger.info("Frontend", "Reading renderer.js from betterdiscord.asar..."); - bdBody = new Asar(BdAsarUpdater.asarFile.buffer).get("renderer.js"); - runtimeInfo.setBdLoadedFromAsar(true); - } else { Logger.info("Frontend", "Reading betterdiscord.js from local extension folder..."); - bdBody = localRendererResp.body; - runtimeInfo.setBdLoadedFromAsar(false); + runtimeInfo.setBdRendererSource("betterdiscord.js", true); + return localFileContents.body; } - const scriptBody = new TextDecoder().decode(bdBody); + /** + * Tries to load the betterdiscord.asar from the ./dist folder. + * @returns {Promise} + */ + const tryGetLocalBetterDiscordAsar = async () => { + const localFileContents = await tryGetLocalFile("dist/betterdiscord.asar"); + if(!localFileContents) + return; + + Logger.info("Frontend", "Reading betterdiscord.asar from local extension folder..."); + runtimeInfo.setBdRendererSource("betterdiscord.asar", true); + return new Asar(localFileContents.body).get("renderer.js"); + } - runtimeInfo.parseBetterDiscordVersion(scriptBody); + /** + * Tries to load the betterdiscord.asar from the VFS. + * @returns {undefined|ArrayBuffer} + */ + const tryGetVfsBetterDiscordAsar = () => { + Logger.info("Frontend", "Reading betterdiscord.asar in the VFS..."); + runtimeInfo.setBdRendererSource("betterdiscord.asar", false); + return new Asar(BdAsarUpdater.asarFile.buffer).get("renderer.js"); + } - return scriptBody; + /** + * Gets the BetterDiscord renderer script body. + * @returns {Promise} + */ + const getRenderer = async () => { + return await tryGetLocalBetterDiscordJs() || await tryGetLocalBetterDiscordAsar() || tryGetVfsBetterDiscordAsar(); + } + + const bdBodyBuffer = await getRenderer(); + return new TextDecoder().decode(bdBodyBuffer); } /** @@ -79,6 +117,8 @@ async function loadBetterDiscord() { if(!bdScriptBody) return false; + runtimeInfo.parseBetterDiscordVersion(bdScriptBody); + const callback = async () => { DiscordModules.Dispatcher.unsubscribe(connectionOpenEvent, callback); try { diff --git a/manifest.json b/manifest.json index 956918a..6b0ad7c 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { - "name": "BDBrowser", - "version": "1.9.1.20230402", - "description": "Allows you to use BetterDiscord on the web client. Some plugins might not be working correctly.", + "name": "__MSG_extName__", + "version": "1.9.1.20230415", + "description": "__MSG_extDesc__", "homepage_url": "https://github.com/tsukasa/BdBrowser", "icons": { "16": "assets/chrome/logo.png", @@ -9,6 +9,7 @@ "128": "assets/chrome/logo.png" }, "manifest_version": 3, + "default_locale": "en", "permissions": [ "declarativeNetRequestWithHostAccess", "storage" @@ -37,6 +38,7 @@ "web_accessible_resources": [{ "resources": [ "assets/spinner.webm", + "dist/betterdiscord.asar", "dist/betterdiscord.js", "dist/frontend.js", "dist/preload.js"