this repo has no description
at v1.2.1 3.3 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 { 9 getExtensionsPath, 10 getMoonlightDir 11} from "@moonlight-mod/core/util/data"; 12import Logger, { initLogger } from "@moonlight-mod/core/util/logger"; 13import { 14 loadExtensions, 15 loadProcessedExtensions 16} from "@moonlight-mod/core/extension/loader"; 17import createFS from "@moonlight-mod/core/fs"; 18 19async function injectGlobals() { 20 global.moonlightFS = createFS(); 21 22 const config = await readConfig(); 23 initLogger(config); 24 const extensions = await getExtensions(); 25 const processedExtensions = await loadExtensions(extensions); 26 const moonlightDir = await getMoonlightDir(); 27 const extensionsPath = await getExtensionsPath(); 28 29 function getConfig(ext: string) { 30 const val = config.extensions[ext]; 31 if (val == null || typeof val === "boolean") return undefined; 32 return val.config; 33 } 34 35 global.moonlightNode = { 36 config, 37 extensions, 38 processedExtensions, 39 nativesCache: {}, 40 isBrowser: false, 41 42 version: MOONLIGHT_VERSION, 43 branch: MOONLIGHT_BRANCH as MoonlightBranch, 44 45 getConfig, 46 getConfigOption: <T>(ext: string, name: string) => { 47 const config = getConfig(ext); 48 if (config == null) return undefined; 49 const option = config[name]; 50 if (option == null) return undefined; 51 return option as T; 52 }, 53 getNatives: (ext: string) => global.moonlightNode.nativesCache[ext], 54 getLogger: (id: string) => { 55 return new Logger(id); 56 }, 57 58 getMoonlightDir() { 59 return moonlightDir; 60 }, 61 getExtensionDir: (ext: string) => { 62 return path.join(extensionsPath, ext); 63 }, 64 writeConfig 65 }; 66 67 await loadProcessedExtensions(processedExtensions); 68 contextBridge.exposeInMainWorld("moonlightNode", moonlightNode); 69 70 const extCors = moonlightNode.processedExtensions.extensions.flatMap( 71 (x) => x.manifest.cors ?? [] 72 ); 73 74 for (const repo of moonlightNode.config.repositories) { 75 const url = new URL(repo); 76 url.pathname = "/"; 77 extCors.push(url.toString()); 78 } 79 80 ipcRenderer.invoke(constants.ipcSetCorsList, extCors); 81 82 const extBlocked = moonlightNode.processedExtensions.extensions.flatMap( 83 (e) => e.manifest.blocked ?? [] 84 ); 85 ipcRenderer.invoke(constants.ipcSetBlockedList, extBlocked); 86} 87 88async function loadPreload() { 89 const webPreloadPath = path.join(__dirname, "web-preload.js"); 90 const webPreload = fs.readFileSync(webPreloadPath, "utf8"); 91 await webFrame.executeJavaScript(webPreload); 92} 93 94async function init(oldPreloadPath: string) { 95 try { 96 await injectGlobals(); 97 await loadPreload(); 98 } catch (e) { 99 const message = e instanceof Error ? e.stack : e; 100 await ipcRenderer.invoke(constants.ipcMessageBox, { 101 title: "moonlight node-preload error", 102 message: message 103 }); 104 } 105 106 // Let Discord start even if we fail 107 if (oldPreloadPath) require(oldPreloadPath); 108} 109 110const oldPreloadPath: string = ipcRenderer.sendSync( 111 constants.ipcGetOldPreloadPath 112); 113init(oldPreloadPath);