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