this repo has no description
at v1.2.5 3.9 kB view raw
1import { webFrame, ipcRenderer, contextBridge } from "electron"; 2import fs from "node:fs"; 3import path from "node:path"; 4 5import { readConfig, writeConfig } from "@moonlight-mod/core/config"; 6import { constants, MoonlightBranch } from "@moonlight-mod/types"; 7import { getExtensions } from "@moonlight-mod/core/extension"; 8import { getExtensionsPath, getMoonlightDir } from "@moonlight-mod/core/util/data"; 9import Logger, { initLogger } from "@moonlight-mod/core/util/logger"; 10import { loadExtensions, loadProcessedExtensions } from "@moonlight-mod/core/extension/loader"; 11import createFS from "@moonlight-mod/core/fs"; 12import { registerCors, registerBlocked, getDynamicCors } from "@moonlight-mod/core/cors"; 13import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config"; 14 15let initialized = false; 16 17function setCors() { 18 const data = getDynamicCors(); 19 ipcRenderer.invoke(constants.ipcSetCorsList, data.cors); 20 ipcRenderer.invoke(constants.ipcSetBlockedList, data.blocked); 21} 22 23async function injectGlobals() { 24 global.moonlightNodeSandboxed = { 25 fs: createFS(), 26 addCors(url) { 27 registerCors(url); 28 if (initialized) setCors(); 29 }, 30 addBlocked(url) { 31 registerBlocked(url); 32 if (initialized) setCors(); 33 } 34 }; 35 36 let config = await readConfig(); 37 initLogger(config); 38 const extensions = await getExtensions(); 39 const processedExtensions = await loadExtensions(extensions); 40 const moonlightDir = await getMoonlightDir(); 41 const extensionsPath = await getExtensionsPath(); 42 43 global.moonlightNode = { 44 get config() { 45 return config; 46 }, 47 extensions, 48 processedExtensions, 49 nativesCache: {}, 50 isBrowser: false, 51 52 version: MOONLIGHT_VERSION, 53 branch: MOONLIGHT_BRANCH as MoonlightBranch, 54 55 getConfig(ext) { 56 return getConfig(ext, config); 57 }, 58 getConfigOption(ext, name) { 59 const manifest = getManifest(extensions, ext); 60 return getConfigOption(ext, name, config, manifest); 61 }, 62 setConfigOption(ext, name, value) { 63 setConfigOption(config, ext, name, value); 64 this.writeConfig(config); 65 }, 66 67 getNatives: (ext: string) => global.moonlightNode.nativesCache[ext], 68 getLogger: (id: string) => { 69 return new Logger(id); 70 }, 71 72 getMoonlightDir() { 73 return moonlightDir; 74 }, 75 getExtensionDir: (ext: string) => { 76 return path.join(extensionsPath, ext); 77 }, 78 async writeConfig(newConfig) { 79 await writeConfig(newConfig); 80 config = newConfig; 81 } 82 }; 83 84 await loadProcessedExtensions(processedExtensions); 85 contextBridge.exposeInMainWorld("moonlightNode", moonlightNode); 86 87 const extCors = moonlightNode.processedExtensions.extensions.flatMap((x) => x.manifest.cors ?? []); 88 for (const cors of extCors) { 89 registerCors(cors); 90 } 91 92 for (const repo of moonlightNode.config.repositories) { 93 const url = new URL(repo); 94 url.pathname = "/"; 95 registerCors(url.toString()); 96 } 97 98 const extBlocked = moonlightNode.processedExtensions.extensions.flatMap((e) => e.manifest.blocked ?? []); 99 for (const blocked of extBlocked) { 100 registerBlocked(blocked); 101 } 102 103 setCors(); 104 105 initialized = true; 106} 107 108async function loadPreload() { 109 const webPreloadPath = path.join(__dirname, "web-preload.js"); 110 const webPreload = fs.readFileSync(webPreloadPath, "utf8"); 111 await webFrame.executeJavaScript(webPreload); 112} 113 114async function init(oldPreloadPath: string) { 115 try { 116 await injectGlobals(); 117 await loadPreload(); 118 } catch (e) { 119 const message = e instanceof Error ? e.stack : e; 120 await ipcRenderer.invoke(constants.ipcMessageBox, { 121 title: "moonlight node-preload error", 122 message: message 123 }); 124 } 125 126 // Let Discord start even if we fail 127 if (oldPreloadPath) require(oldPreloadPath); 128} 129 130const oldPreloadPath: string = ipcRenderer.sendSync(constants.ipcGetOldPreloadPath); 131init(oldPreloadPath);