diff --git a/PrismLauncherPortable/App/AppInfo/Launcher/PrismLauncherPortable.ini b/PrismLauncherPortable/App/AppInfo/Launcher/PrismLauncherPortable.ini index 1171d39..62301d6 100644 --- a/PrismLauncherPortable/App/AppInfo/Launcher/PrismLauncherPortable.ini +++ b/PrismLauncherPortable/App/AppInfo/Launcher/PrismLauncherPortable.ini @@ -9,4 +9,4 @@ WaitForProgram=false WaitForOtherInstances=false [Environment] -PRISMLAUNCHER_JAVA_PATHS="..\..\CommonFiles\Java\bin\javaw.exe;..\..\CommonFiles\Java64\bin\javaw.exe;..\..\CommonFiles\JDK\bin\javaw.exe;..\..\CommonFiles\JDK64\bin\javaw.exe;..\..\CommonFiles\OpenJDK\bin\javaw.exe;..\..\CommonFiles\OpenJDK64\bin\javaw.exe;..\..\CommonFiles\OpenJDKJRE\bin\javaw.exe;..\..\CommonFiles\OpenJDKJRE64\bin\javaw.exe" +PRISMLAUNCHER_JAVA_PATHS="..\..\CommonFiles\Java\bin\javaw.exe;..\..\CommonFiles\Java64\bin\javaw.exe;..\..\CommonFiles\JDK\bin\javaw.exe;..\..\CommonFiles\JDK64\bin\javaw.exe;..\..\CommonFiles\OpenJDK\bin\javaw.exe;..\..\CommonFiles\OpenJDK64\bin\javaw.exe;..\..\CommonFiles\OpenJDKJRE\bin\javaw.exe;..\..\CommonFiles\OpenJDKJRE64\bin\javaw.exe;..\App\jre8\bin\javaw.exe;..\App\jre17\bin\javaw.exe;..\App\jre21\bin\javaw.exe" diff --git a/deno.json b/deno.json index 97b3e79..c78663f 100644 --- a/deno.json +++ b/deno.json @@ -1,15 +1,16 @@ { "tasks": { - "update": "deno run -A update.ts", - "fileinfo": "deno run -A fileinfo.ts" + "start": "deno run -A src/main.ts", + "fileinfo": "deno run -A src/fileinfo.ts" }, "imports": { - "@david/dax": "jsr:@david/dax@^0.39.2", - "@std/crypto": "jsr:@std/crypto@^0.218.2", - "@std/encoding": "jsr:@std/encoding@^0.218.2", - "@std/fmt": "jsr:@std/fmt@^0.218.2", - "@std/ini": "jsr:@std/ini@^0.218.2", - "@zip-js/zip-js": "jsr:@zip-js/zip-js@^2.7.37", - "zod": "npm:zod@^3.22.4" + "@david/dax": "jsr:@david/dax@^0.40.1", + "@std/crypto": "jsr:@std/crypto@^0.223.0", + "@std/dotenv": "jsr:@std/dotenv@^0.223.0", + "@std/encoding": "jsr:@std/encoding@^0.223.0", + "@std/fmt": "jsr:@std/fmt@^0.223.0", + "@std/ini": "jsr:@std/ini@^0.223.0", + "@zip-js/zip-js": "jsr:@zip-js/zip-js@^2.7.42", + "zod": "npm:zod@^3.23.4" } } diff --git a/deno.lock b/deno.lock index 68be60d..701bea5 100644 --- a/deno.lock +++ b/deno.lock @@ -2,101 +2,105 @@ "version": "3", "packages": { "specifiers": { - "jsr:@david/dax@^0.39.2": "jsr:@david/dax@0.39.2", + "jsr:@david/dax@^0.40.1": "jsr:@david/dax@0.40.1", "jsr:@david/which@0.3": "jsr:@david/which@0.3.0", - "jsr:@std/assert@^0.213.0": "jsr:@std/assert@0.213.1", - "jsr:@std/assert@^0.218.2": "jsr:@std/assert@0.218.2", - "jsr:@std/bytes@^0.213.0": "jsr:@std/bytes@0.213.1", - "jsr:@std/crypto@^0.218.2": "jsr:@std/crypto@0.218.2", - "jsr:@std/encoding@^0.218.2": "jsr:@std/encoding@0.218.2", - "jsr:@std/fmt@0.213.0": "jsr:@std/fmt@0.213.0", - "jsr:@std/fmt@^0.218.2": "jsr:@std/fmt@0.218.2", - "jsr:@std/fs@0.213.0": "jsr:@std/fs@0.213.0", - "jsr:@std/ini@^0.218.2": "jsr:@std/ini@0.218.2", - "jsr:@std/io@0.213.0": "jsr:@std/io@0.213.0", - "jsr:@std/io@^0.213.0": "jsr:@std/io@0.213.0", - "jsr:@std/path@0.213.0": "jsr:@std/path@0.213.0", - "jsr:@std/path@^0.213.0": "jsr:@std/path@0.213.0", - "jsr:@std/streams@0.213.0": "jsr:@std/streams@0.213.0", - "jsr:@zip-js/zip-js@^2.7.37": "jsr:@zip-js/zip-js@2.7.37", - "npm:zod@^3.22.4": "npm:zod@3.22.4" + "jsr:@std/assert@^0.221.0": "jsr:@std/assert@0.221.0", + "jsr:@std/assert@^0.223.0": "jsr:@std/assert@0.223.0", + "jsr:@std/bytes@^0.221.0": "jsr:@std/bytes@0.221.0", + "jsr:@std/crypto@^0.223.0": "jsr:@std/crypto@0.223.0", + "jsr:@std/dotenv@^0.223.0": "jsr:@std/dotenv@0.223.0", + "jsr:@std/encoding@^0.223.0": "jsr:@std/encoding@0.223.0", + "jsr:@std/fmt@^0.221.0": "jsr:@std/fmt@0.221.0", + "jsr:@std/fmt@^0.223.0": "jsr:@std/fmt@0.223.0", + "jsr:@std/fs@0.221.0": "jsr:@std/fs@0.221.0", + "jsr:@std/ini@^0.223.0": "jsr:@std/ini@0.223.0", + "jsr:@std/io@0.221.0": "jsr:@std/io@0.221.0", + "jsr:@std/io@^0.221.0": "jsr:@std/io@0.221.0", + "jsr:@std/path@0.221.0": "jsr:@std/path@0.221.0", + "jsr:@std/path@^0.221.0": "jsr:@std/path@0.221.0", + "jsr:@std/streams@0.221.0": "jsr:@std/streams@0.221.0", + "jsr:@zip-js/zip-js@^2.7.42": "jsr:@zip-js/zip-js@2.7.42", + "npm:zod@^3.23.4": "npm:zod@3.23.4" }, "jsr": { - "@david/dax@0.39.2": { - "integrity": "f7fde219e9a4b331024bcc89bfc5c63b85348cad61ff26a963d893262d92b01c", + "@david/dax@0.40.1": { + "integrity": "0c71d32a0484d3904f586417995f8ec26d45144f0eba95d3e5bb03b640b6df59", "dependencies": [ "jsr:@david/which@0.3", - "jsr:@std/fmt@0.213.0", - "jsr:@std/fs@0.213.0", - "jsr:@std/io@0.213.0", - "jsr:@std/path@0.213.0", - "jsr:@std/streams@0.213.0" + "jsr:@std/fmt@^0.221.0", + "jsr:@std/fs@0.221.0", + "jsr:@std/io@0.221.0", + "jsr:@std/path@0.221.0", + "jsr:@std/streams@0.221.0" ] }, "@david/which@0.3.0": { "integrity": "6bdb62c40ac90edcf328e854fa8103a8db21e7c326089cbe3c3a1cf7887d3204" }, - "@std/assert@0.213.1": { - "integrity": "24c28178b30c8e0782c18e8e94ea72b16282207569cdd10ffb9d1d26f2edebfe" + "@std/assert@0.221.0": { + "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" }, - "@std/assert@0.218.2": { - "integrity": "7f0a5a1a8cf86607cd6c2c030584096e1ffad27fc9271429a8cb48cfbdee5eaf" + "@std/assert@0.223.0": { + "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24" }, - "@std/bytes@0.213.1": { - "integrity": "97f133c5bfb18b4522675e0822089de91e32618a4d8c2fcea8e175aca8f1f65c" + "@std/bytes@0.221.0": { + "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" }, - "@std/crypto@0.218.2": { - "integrity": "8c5031a3a1c3ac3bed3c0d4bed2fe7e7faedcb673bbfa0edd10570c8452f5cd2", + "@std/crypto@0.223.0": { + "integrity": "1aa9555ff56b09e197ad988ea200f84bc6781fd4fd83f3a156ee44449af93000", "dependencies": [ - "jsr:@std/assert@^0.218.2", - "jsr:@std/encoding@^0.218.2" + "jsr:@std/assert@^0.223.0", + "jsr:@std/encoding@^0.223.0" ] }, - "@std/encoding@0.218.2": { - "integrity": "da55a763c29bf0dbf06fd286430b358266eb99c28789d89fe9a3e28edecb8d8e" + "@std/dotenv@0.223.0": { + "integrity": "9ec65949815cb3dbf43ca082c0e299bcf528ff736fdb612db9274464059d49f4" }, - "@std/fmt@0.213.0": { - "integrity": "4623054b309ee60e37cc3db2bc55385aa129bb899f0c50e912d79a763aee6b6a" + "@std/encoding@0.223.0": { + "integrity": "2b5615a75e00337ce113f34cf2f9b8c18182c751a8dcc8b1a2c2fc0e117bef00" }, - "@std/fmt@0.218.2": { - "integrity": "99526449d2505aa758b6cbef81e7dd471d8b28ec0dcb1491d122b284c548788a" + "@std/fmt@0.221.0": { + "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" }, - "@std/fs@0.213.0": { - "integrity": "607ed7611e61e33179e2a6a7c60c086d6fef3b79438c403c51a336d0ca4e162d", + "@std/fmt@0.223.0": { + "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208" + }, + "@std/fs@0.221.0": { + "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", "dependencies": [ - "jsr:@std/assert@^0.213.0", - "jsr:@std/path@^0.213.0" + "jsr:@std/assert@^0.221.0", + "jsr:@std/path@^0.221.0" ] }, - "@std/ini@0.218.2": { - "integrity": "ade2bd22468b74c9a065221238f73c0184469b16dbd9b0e352481f80ca20a8d4" + "@std/ini@0.223.0": { + "integrity": "37eaab8a861b74ff248169a4f14b45830461eab8f4c374031c753ad0dac4d062" }, - "@std/io@0.213.0": { - "integrity": "e78db92000e718c4b37e3c5f8a854a7c8d66cf4f1ab81d2c5c834172e66191cb", + "@std/io@0.221.0": { + "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", "dependencies": [ - "jsr:@std/assert@^0.213.0", - "jsr:@std/bytes@^0.213.0" + "jsr:@std/assert@^0.221.0", + "jsr:@std/bytes@^0.221.0" ] }, - "@std/path@0.213.0": { - "integrity": "9488ae5c052132130ac8ae406aafe1db2a407d6839ac0e8896c99497ff59087e", + "@std/path@0.221.0": { + "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", "dependencies": [ - "jsr:@std/assert@^0.213.0" + "jsr:@std/assert@^0.221.0" ] }, - "@std/streams@0.213.0": { - "integrity": "14519c7ce5f4c88de2e365f4bf1b8371c942a9fe0e1f9a0b9e10a56e3c3e3877", + "@std/streams@0.221.0": { + "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", "dependencies": [ - "jsr:@std/io@^0.213.0" + "jsr:@std/io@^0.221.0" ] }, - "@zip-js/zip-js@2.7.37": { - "integrity": "cf14ddf7472202e5f77f7db078372e489175f562934593f82c1e15d2d1000bcc" + "@zip-js/zip-js@2.7.42": { + "integrity": "189523b5d9b73025d576f053de17af7d2f7d827cf695b2cf345a38dac50a911d" } }, "npm": { - "zod@3.22.4": { - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "zod@3.23.4": { + "integrity": "sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==", "dependencies": {} } } @@ -104,13 +108,14 @@ "remote": {}, "workspace": { "dependencies": [ - "jsr:@david/dax@^0.39.2", - "jsr:@std/crypto@^0.218.2", - "jsr:@std/encoding@^0.218.2", - "jsr:@std/fmt@^0.218.2", - "jsr:@std/ini@^0.218.2", - "jsr:@zip-js/zip-js@^2.7.37", - "npm:zod@^3.22.4" + "jsr:@david/dax@^0.40.1", + "jsr:@std/crypto@^0.223.0", + "jsr:@std/dotenv@^0.223.0", + "jsr:@std/encoding@^0.223.0", + "jsr:@std/fmt@^0.223.0", + "jsr:@std/ini@^0.223.0", + "jsr:@zip-js/zip-js@^2.7.42", + "npm:zod@^3.23.4" ] } } diff --git a/fileinfo.ts b/src/fileinfo.ts similarity index 100% rename from fileinfo.ts rename to src/fileinfo.ts diff --git a/src/java.ts b/src/java.ts new file mode 100644 index 0000000..440754d --- /dev/null +++ b/src/java.ts @@ -0,0 +1,42 @@ +import z from "zod"; +import $ from "@david/dax"; + +export type JavaVersion = 8 | 17 | 21; + +const Release = z.object({ + release_name: z.string(), + release_link: z.string().url(), + binary: z.object({ + package: z.object({ + name: z.string(), + link: z.string(), + size: z.number(), + }), + }), + version: z.object({ + openjdk_version: z.string(), + }), +}); +type Release = z.infer; + +const cache = new Map(); + +export async function getJavaRelease(version: JavaVersion): Promise { + const cached = cache.get(version); + if (cached) return cached; + + const params = new URLSearchParams({ + architecture: "x64", + image_type: "jre", + os: "windows", + vendor: "eclipse", + }); + const url = `https://api.adoptium.net/v3/assets/latest/${version}/hotspot?${params}`; + const release = z.tuple([Release]).parse(await $.request(url).json())[0]; + cache.set(version, release); + return release; +} + +if (import.meta.main) { + $.log(await getJavaRelease(21)); +} diff --git a/update.ts b/src/main.ts similarity index 56% rename from update.ts rename to src/main.ts index 1cb8274..b97ec0a 100644 --- a/update.ts +++ b/src/main.ts @@ -1,14 +1,13 @@ -import { z } from "zod"; +import z from "zod"; import $ from "@david/dax"; import * as ini from "@std/ini"; -import { ZipReader, HttpReader, Uint8ArrayWriter } from "@zip-js/zip-js"; +import { ZipReader, Uint8ArrayWriter } from "@zip-js/zip-js"; +import { getLatestPrism } from "./prism.ts"; +import { JavaVersion, getJavaRelease } from "./java.ts"; +import * as dotenv from "@std/dotenv"; $.setPrintCommand(true); -const GitHubRelease = z.object({ - tag_name: z.string(), -}); - const AppInfoIni = z.object({ Version: z.object({ PackageVersion: z.string(), @@ -17,11 +16,7 @@ const AppInfoIni = z.object({ }); type AppInfoIni = z.infer; -const latestVersion = GitHubRelease.parse( - await $.request( - "https://api.github.com/repos/PrismLauncher/PrismLauncher/releases/latest" - ).json() -).tag_name; +const latestVersion = (await getLatestPrism()).tag_name; const appPath = $.path("PrismLauncherPortable").join("App"); const iniPath = appPath.join("AppInfo", "appinfo.ini"); @@ -32,7 +27,7 @@ const versionArray = appinfo.Version.PackageVersion.split("."); const currentVersion = versionArray.slice(0, 2).join("."); const updateAvailable = currentVersion != latestVersion; -$.log( +$.logLight( `Old version: ${appinfo.Version.DisplayVersion} (${appinfo.Version.PackageVersion})` ); const updateNum = updateAvailable ? 0 : parseInt(versionArray[2]) + 1; @@ -69,26 +64,15 @@ const downloads: Download[] = [ ]; if (updateAvailable || (await $.confirm("Redownload Prism Launcher?"))) { - $.logLight("Downloading..."); - - for await (const entry of appPath.readDir()) { - if (!entry.isDirectory) continue; - if (entry.name == "AppInfo") continue; - - const path = appPath.join(entry.name); - await path.remove({ recursive: true }); - } - for (const download of downloads) { const path = appPath.join(download.dir); const url = `${urlBase}/${download.filename}`; + await path.emptyDir(); - const zipReader = new ZipReader(new HttpReader(url)); + const req = await $.request(url).showProgress({ noClear: true }); + const zipReader = new ZipReader(req); const entries = await zipReader.getEntries(); - $.logStep("Downloaded", download.filename); - await path.ensureDir(); - for (const entry of entries) { if (!entry.getData) continue; if (entry.filename == "prismlauncher_updater.exe") continue; @@ -96,12 +80,50 @@ if (updateAvailable || (await $.confirm("Redownload Prism Launcher?"))) { const uint8 = await entry.getData(new Uint8ArrayWriter()); const filePath = path.join(entry.filename); - if (entry.directory) await filePath.mkdir(); + if (entry.directory) await filePath.ensureDir(); else await filePath.write(uint8); } } } +async function getJavaVer(version: JavaVersion) { + const relFile = appPath.join(`jre${version}`, "release"); + if (!(await relFile.exists())) return; + + const data = dotenv.parse(await relFile.readText()); + return { java: data.JAVA_VERSION, full: data.FULL_VERSION }; +} + +async function updateJava(version: JavaVersion) { + const jreDir = appPath.join(`jre${version}`); + const release = await getJavaRelease(version); + if (release.version.openjdk_version == (await getJavaVer(version))?.full) { + $.logLight(`Skipping Java ${version} (Already up to date)`); + return; + } + jreDir.emptyDir(); + + const url = release.binary.package.link; + const req = await $.request(url).showProgress({ noClear: true }); + const zipReader = new ZipReader(req); + const entries = await zipReader.getEntries(); + + for (const entry of entries) { + if (!entry.getData) continue; + + const uint8 = await entry.getData(new Uint8ArrayWriter()); + const filename = entry.filename.split("/").slice(1).join("/"); + const filePath = jreDir.join(filename); + + if (entry.directory) await filePath.ensureDir(); + else await filePath.write(uint8); + } +} + +await updateJava(8); +await updateJava(17); +await updateJava(21); + if (updateAvailable || (await $.confirm("Create launcher and installer?"))) { $.logStep("Creating launcher"); await $`PortableApps.comLauncher/PortableApps.comLauncherGenerator.exe $PWD\\PrismLauncherPortable`; @@ -109,9 +131,19 @@ if (updateAvailable || (await $.confirm("Create launcher and installer?"))) { await $`PortableApps.comInstaller/PortableApps.comInstaller.exe $PWD\\PrismLauncherPortable`; } +async function logJavaVersion(version: JavaVersion) { + const release = await getJavaRelease(version); + const vers = (await getJavaVer(version))?.java; + $.log(`- Includes [Java ${vers}](${release.release_link})`); +} + +$.log(); $.log( - `- ${ - updateAvailable ? "Update to" : "Still using" - } [Prism Launcher ${latestVersion}](https://github.com/PrismLauncher/PrismLauncher/releases/tag/${latestVersion})` + `- Using [Prism Launcher ${latestVersion}](https://prismlauncher.org/news/release-${latestVersion})` ); +await logJavaVersion(8); +await logJavaVersion(17); +await logJavaVersion(21); +$.log(); + alert("Done!"); diff --git a/src/prism.ts b/src/prism.ts new file mode 100644 index 0000000..2d0edb1 --- /dev/null +++ b/src/prism.ts @@ -0,0 +1,30 @@ +import z from "zod"; +import $ from "@david/dax"; + +const GHAsset = z.object({ + name: z.string(), + size: z.number(), + browser_download_url: z.string().url(), +}); + +const GHRelease = z.object({ + name: z.string(), + tag_name: z.string(), + assets: GHAsset.array(), +}); +type GHRelease = z.infer; + +let cache: GHRelease | undefined; + +export async function getLatestPrism(): Promise { + if (cache) return cache; + + const url = + "https://api.github.com/repos/PrismLauncher/PrismLauncher/releases/latest"; + cache = GHRelease.parse(await $.request(url).json()); + return cache; +} + +if (import.meta.main) { + $.log(await getLatestPrism()); +} diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..c6b4ae0 --- /dev/null +++ b/start.bat @@ -0,0 +1 @@ +@deno task start diff --git a/update.bat b/update.bat deleted file mode 100644 index 678c43f..0000000 --- a/update.bat +++ /dev/null @@ -1 +0,0 @@ -@deno task update