this repo has no description

Implement update checking, no UI for now

Changed files
+108 -4
.github
packages
browser
src
core-extensions
src
moonbase
webpackModules
injector
src
node-preload
src
types
web-preload
src
+2
.github/workflows/nightly.yml
··· 31 - name: Build moonlight 32 env: 33 NODE_ENV: production 34 run: pnpm run build 35 36 - name: Write ref/commit to file
··· 31 - name: Build moonlight 32 env: 33 NODE_ENV: production 34 + MOONLIGHT_BRANCH: nightly 35 + MOONLIGHT_VERSION: ${{ github.sha }} 36 run: pnpm run build 37 38 - name: Write ref/commit to file
+2
.github/workflows/release.yml
··· 29 - name: Build moonlight 30 env: 31 NODE_ENV: production 32 run: pnpm run build 33 - name: Create archive 34 run: |
··· 29 - name: Build moonlight 30 env: 31 NODE_ENV: production 32 + MOONLIGHT_BRANCH: stable 33 + MOONLIGHT_VERSION: ${{ github.ref_name }} 34 run: pnpm run build 35 - name: Create archive 36 run: |
+6 -1
build.mjs
··· 16 const browser = process.argv.includes("--browser"); 17 const mv2 = process.argv.includes("--mv2"); 18 19 const external = [ 20 "electron", 21 "fs", ··· 96 97 const define = { 98 MOONLIGHT_ENV: `"${name}"`, 99 - MOONLIGHT_PROD: prod.toString() 100 }; 101 102 for (const iterName of [
··· 16 const browser = process.argv.includes("--browser"); 17 const mv2 = process.argv.includes("--mv2"); 18 19 + const buildBranch = process.env.MOONLIGHT_BRANCH ?? "dev"; 20 + const buildVersion = process.env.MOONLIGHT_VERSION ?? "dev"; 21 + 22 const external = [ 23 "electron", 24 "fs", ··· 99 100 const define = { 101 MOONLIGHT_ENV: `"${name}"`, 102 + MOONLIGHT_PROD: prod.toString(), 103 + MOONLIGHT_BRANCH: `"${buildBranch}"`, 104 + MOONLIGHT_VERSION: `"${buildVersion}"` 105 }; 106 107 for (const iterName of [
+6
packages/browser/src/index.ts
··· 103 processedExtensions, 104 nativesCache: {}, 105 106 getConfig, 107 getConfigOption: <T>(ext: string, name: string) => { 108 const config = getConfig(ext); ··· 116 return new Logger(id); 117 }, 118 119 getExtensionDir: (ext: string) => { 120 return `/extensions/${ext}`; 121 },
··· 103 processedExtensions, 104 nativesCache: {}, 105 106 + version: MOONLIGHT_VERSION, 107 + branch: MOONLIGHT_BRANCH, 108 + 109 getConfig, 110 getConfigOption: <T>(ext: string, name: string) => { 111 const config = getConfig(ext); ··· 119 return new Logger(id); 120 }, 121 122 + getMoonlightDir() { 123 + return "/"; 124 + }, 125 getExtensionDir: (ext: string) => { 126 return `/extensions/${ext}`; 127 },
+57 -2
packages/core-extensions/src/moonbase/node.ts
··· 6 7 const logger = moonlightNode.getLogger("moonbase"); 8 9 async function fetchRepositories(repos: string[]) { 10 const ret: Record<string, RepositoryManifest[]> = {}; 11 12 for (const repo of repos) { 13 try { 14 - const req = await fetch(repo); 15 const json = await req.json(); 16 ret[repo] = json; 17 } catch (e) { ··· 27 url: string, 28 repo: string 29 ) { 30 - const req = await fetch(url); 31 32 const dir = moonlightNode.getExtensionDir(manifest.id); 33 // remake it in case of updates ··· 63 } 64 65 const exports: MoonbaseNatives = { 66 fetchRepositories, 67 installExtension, 68 deleteExtension,
··· 6 7 const logger = moonlightNode.getLogger("moonbase"); 8 9 + const updateTimerFile = path.join( 10 + moonlightNode.getMoonlightDir(), 11 + ".moonbase-update-timer" 12 + ); 13 + const updateTimerInterval = 12 * 60 * 60 * 1000; 14 + 15 + const githubRepo = "moonlight-mod/moonlight"; 16 + const nightlyRefUrl = "https://moonlight-mod.github.io/moonlight/ref"; 17 + const userAgent = `moonlight/${moonlightNode.version} (https://github.com/moonlight-mod/moonlight)`; 18 + 19 + async function checkForMoonlightUpdate() { 20 + const updateTimerStr = fs.existsSync(updateTimerFile) 21 + ? fs.readFileSync(updateTimerFile, "utf-8") 22 + : "0"; 23 + let updateTimer = parseInt(updateTimerStr); 24 + if (isNaN(updateTimer)) updateTimer = 0; 25 + 26 + const shouldCheck = Date.now() - updateTimer > updateTimerInterval; 27 + if (!shouldCheck) return null; 28 + 29 + fs.writeFileSync(updateTimerFile, Date.now().toString()); 30 + 31 + if (moonlightNode.branch === "stable") { 32 + const req = await fetch( 33 + `https://api.github.com/repos/${githubRepo}/releases/latest`, 34 + { 35 + headers: { 36 + "User-Agent": userAgent 37 + } 38 + } 39 + ); 40 + const json: { name: string } = await req.json(); 41 + return json.name !== moonlightNode.version ? json.name : null; 42 + } else if (moonlightNode.branch === "nightly") { 43 + const req = await fetch(nightlyRefUrl, { 44 + headers: { 45 + "User-Agent": userAgent 46 + } 47 + }); 48 + const ref = (await req.text()).split("\n")[0]; 49 + return ref !== moonlightNode.version ? ref : null; 50 + } 51 + 52 + return null; 53 + } 54 + 55 async function fetchRepositories(repos: string[]) { 56 const ret: Record<string, RepositoryManifest[]> = {}; 57 58 for (const repo of repos) { 59 try { 60 + const req = await fetch(repo, { 61 + headers: { 62 + "User-Agent": userAgent 63 + } 64 + }); 65 const json = await req.json(); 66 ret[repo] = json; 67 } catch (e) { ··· 77 url: string, 78 repo: string 79 ) { 80 + const req = await fetch(url, { 81 + headers: { 82 + "User-Agent": userAgent 83 + } 84 + }); 85 86 const dir = moonlightNode.getExtensionDir(manifest.id); 87 // remake it in case of updates ··· 117 } 118 119 const exports: MoonbaseNatives = { 120 + checkForMoonlightUpdate, 121 fetchRepositories, 122 installExtension, 123 deleteExtension,
+1
packages/core-extensions/src/moonbase/types.ts
··· 1 import { DetectedExtension, ExtensionManifest } from "types/src"; 2 3 export type MoonbaseNatives = { 4 fetchRepositories( 5 repos: string[] 6 ): Promise<Record<string, RepositoryManifest[]>>;
··· 1 import { DetectedExtension, ExtensionManifest } from "types/src"; 2 3 export type MoonbaseNatives = { 4 + checkForMoonlightUpdate(): Promise<string | null>; 5 fetchRepositories( 6 repos: string[] 7 ): Promise<Record<string, RepositoryManifest[]>>;
+5
packages/core-extensions/src/moonbase/webpackModules/stores.ts
··· 16 if (window._moonlightBrowserFS != null) { 17 const browserFS = window._moonlightBrowserFS!; 18 natives = { 19 fetchRepositories: async (repos) => { 20 const ret: Record<string, RepositoryManifest[]> = {}; 21
··· 16 if (window._moonlightBrowserFS != null) { 17 const browserFS = window._moonlightBrowserFS!; 18 natives = { 19 + checkForMoonlightUpdate: async () => { 20 + // TODO 21 + return null; 22 + }, 23 + 24 fetchRepositories: async (repos) => { 25 const ret: Record<string, RepositoryManifest[]> = {}; 26
+3
packages/injector/src/index.ts
··· 183 dependencyGraph: new Map() 184 }, 185 186 getConfig, 187 getConfigOption: <T>(ext: string, name: string) => { 188 const config = getConfig(ext);
··· 183 dependencyGraph: new Map() 184 }, 185 186 + version: MOONLIGHT_VERSION, 187 + branch: MOONLIGHT_BRANCH, 188 + 189 getConfig, 190 getConfigOption: <T>(ext: string, name: string) => { 191 const config = getConfig(ext);
+11 -1
packages/node-preload/src/index.ts
··· 5 import { readConfig, writeConfig } from "@moonlight-mod/core/config"; 6 import { constants } from "@moonlight-mod/types"; 7 import { getExtensions } from "@moonlight-mod/core/extension"; 8 - import { getExtensionsPath } from "@moonlight-mod/core/util/data"; 9 import Logger, { initLogger } from "@moonlight-mod/core/util/logger"; 10 import { 11 loadExtensions, ··· 29 extensions, 30 processedExtensions, 31 nativesCache: {}, 32 getConfig, 33 getConfigOption: <T>(ext: string, name: string) => { 34 const config = getConfig(ext); ··· 42 return new Logger(id); 43 }, 44 45 getExtensionDir: (ext: string) => { 46 const extPath = getExtensionsPath(); 47 return path.join(extPath, ext);
··· 5 import { readConfig, writeConfig } from "@moonlight-mod/core/config"; 6 import { constants } from "@moonlight-mod/types"; 7 import { getExtensions } from "@moonlight-mod/core/extension"; 8 + import { 9 + getExtensionsPath, 10 + getMoonlightDir 11 + } from "@moonlight-mod/core/util/data"; 12 import Logger, { initLogger } from "@moonlight-mod/core/util/logger"; 13 import { 14 loadExtensions, ··· 32 extensions, 33 processedExtensions, 34 nativesCache: {}, 35 + 36 + version: MOONLIGHT_VERSION, 37 + branch: MOONLIGHT_BRANCH, 38 + 39 getConfig, 40 getConfigOption: <T>(ext: string, name: string) => { 41 const config = getConfig(ext); ··· 49 return new Logger(id); 50 }, 51 52 + getMoonlightDir() { 53 + return getMoonlightDir(); 54 + }, 55 getExtensionDir: (ext: string) => { 56 const extPath = getExtensionsPath(); 57 return path.join(extPath, ext);
+10
packages/types/src/globals.ts
··· 18 extensions: DetectedExtension[]; 19 processedExtensions: ProcessedExtensions; 20 21 getConfig: (ext: string) => ConfigExtension["config"]; 22 getConfigOption: <T>(ext: string, name: string) => T | undefined; 23 getLogger: (id: string) => Logger; ··· 29 processedExtensions: ProcessedExtensions; 30 nativesCache: Record<string, any>; 31 32 getConfig: (ext: string) => ConfigExtension["config"]; 33 getConfigOption: <T>(ext: string, name: string) => T | undefined; 34 getNatives: (ext: string) => any | undefined; 35 getLogger: (id: string) => Logger; 36 37 getExtensionDir: (ext: string) => string; 38 writeConfig: (config: Config) => void; 39 }; ··· 69 registerPatch: (patch: IdentifiedPatch) => void; 70 registerWebpackModule: (module: IdentifiedWebpackModule) => void; 71 }; 72 73 getConfig: (ext: string) => ConfigExtension["config"]; 74 getConfigOption: <T>(ext: string, name: string) => T | undefined;
··· 18 extensions: DetectedExtension[]; 19 processedExtensions: ProcessedExtensions; 20 21 + version: string; 22 + branch: string; 23 + 24 getConfig: (ext: string) => ConfigExtension["config"]; 25 getConfigOption: <T>(ext: string, name: string) => T | undefined; 26 getLogger: (id: string) => Logger; ··· 32 processedExtensions: ProcessedExtensions; 33 nativesCache: Record<string, any>; 34 35 + version: string; 36 + branch: string; 37 + 38 getConfig: (ext: string) => ConfigExtension["config"]; 39 getConfigOption: <T>(ext: string, name: string) => T | undefined; 40 getNatives: (ext: string) => any | undefined; 41 getLogger: (id: string) => Logger; 42 43 + getMoonlightDir: () => string; 44 getExtensionDir: (ext: string) => string; 45 writeConfig: (config: Config) => void; 46 }; ··· 76 registerPatch: (patch: IdentifiedPatch) => void; 77 registerWebpackModule: (module: IdentifiedWebpackModule) => void; 78 }; 79 + 80 + version: string; 81 + branch: string; 82 83 getConfig: (ext: string) => ConfigExtension["config"]; 84 getConfigOption: <T>(ext: string, name: string) => T | undefined;
+2
packages/types/src/index.ts
··· 30 const MOONLIGHT_NODE_PRELOAD: boolean; 31 const MOONLIGHT_WEB_PRELOAD: boolean; 32 const MOONLIGHT_BROWSER: boolean; 33 34 var moonlightHost: MoonlightHost; 35 var moonlightNode: MoonlightNode;
··· 30 const MOONLIGHT_NODE_PRELOAD: boolean; 31 const MOONLIGHT_WEB_PRELOAD: boolean; 32 const MOONLIGHT_BROWSER: boolean; 33 + const MOONLIGHT_BRANCH: string; 34 + const MOONLIGHT_VERSION: string; 35 36 var moonlightHost: MoonlightHost; 37 var moonlightNode: MoonlightNode;
+3
packages/web-preload/src/index.ts
··· 30 registerWebpackModule 31 }, 32 33 getConfig: moonlightNode.getConfig.bind(moonlightNode), 34 getConfigOption: moonlightNode.getConfigOption.bind(moonlightNode), 35 getNatives: moonlightNode.getNatives.bind(moonlightNode),
··· 30 registerWebpackModule 31 }, 32 33 + version: MOONLIGHT_VERSION, 34 + branch: MOONLIGHT_BRANCH, 35 + 36 getConfig: moonlightNode.getConfig.bind(moonlightNode), 37 getConfigOption: moonlightNode.getConfigOption.bind(moonlightNode), 38 getNatives: moonlightNode.getNatives.bind(moonlightNode),