UNPKG

12.1 kBJSONView Raw
1{
2 "name": "@xmcl/installer",
3 "version": "4.2.0",
4 "main": "./dist/index.js",
5 "description": "Provides Minecraft/Forge/Fabric/Liteloader installers",
6 "engines": {
7 "node": ">=10.0"
8 },
9 "publishConfig": {
10 "access": "public",
11 "main": "./dist/index.js",
12 "module": "./dist/index.esm.js"
13 },
14 "dependencies": {
15 "@xmcl/asm": "^0.1.3",
16 "@xmcl/core": "^2.9.0",
17 "@xmcl/forge-site-parser": "^2.0.8",
18 "@xmcl/task": "^4.0.2",
19 "@xmcl/unzip": "^2.0.0",
20 "yauzl": "^2.10.0"
21 },
22 "repository": {
23 "type": "git",
24 "url": "git+https://github.com/Voxelum/minecraft-launcher-core-node.git"
25 },
26 "sideEffects": false,
27 "author": "cijhn@hotmail.com",
28 "keywords": [
29 "minecraft",
30 "typescript",
31 "minecraft-launcher",
32 "nodejs",
33 "electron"
34 ],
35 "license": "MIT",
36 "bugs": {
37 "url": "https://github.com/Voxelum/minecraft-launcher-core-node/issues"
38 },
39 "homepage": "https://github.com/Voxelum/minecraft-launcher-core-node#readme",
40 "devDependencies": {
41 "@types/yauzl": "^2.9.2",
42 "nock": "^12.0.3"
43 },
44 "module": "./dist/index.esm.js",
45 "readme": "# Installer Module\n\n[![npm version](https://img.shields.io/npm/v/@xmcl/installer.svg)](https://www.npmjs.com/package/@xmcl/installer)\n[![Downloads](https://img.shields.io/npm/dm/@xmcl/installer.svg)](https://npmjs.com/@xmcl/installer)\n[![Install size](https://packagephobia.now.sh/badge?p=@xmcl/installer)](https://packagephobia.now.sh/result?p=@xmcl/installer)\n[![npm](https://img.shields.io/npm/l/@xmcl/minecraft-launcher-core.svg)](https://github.com/voxelum/minecraft-launcher-core-node/blob/master/LICENSE)\n[![Build Status](https://github.com/voxelum/minecraft-launcher-core-node/workflows/Build/badge.svg)](https://github.com/Voxelum/minecraft-launcher-core-node/actions?query=workflow%3ABuild)\n\nProvide functions to install Minecraft client, libraries, and assets.\n\n## Usage\n\n### Install Minecraft\n\nFully install vanilla minecraft client including assets and libs.\n\n```ts\n import { getVersionList, MinecraftVersion, install } from \"@xmcl/installer\";\n import { MinecraftLocation } from \"@xmcl/core\";\n\n const minecraft: MinecraftLocation;\n const list: MinecraftVersion[] = (await getVersionList()).versions;\n const aVersion: MinecraftVersion = list[0]; // i just pick the first version in list here\n await install(aVersion, minecraft);\n```\n\nJust install libraries:\n\n```ts\n import { installLibraries } from \"@xmcl/installer\";\n import { ResolvedVersion, MinecraftLocation, Version } from \"@xmcl/core\";\n\n const minecraft: MinecraftLocation;\n const version: string; // version string like 1.13\n const resolvedVersion: ResolvedVersion = await Version.parse(minecraft, version);\n await installLibraries(resolvedVersion);\n```\n\nJust install assets:\n\n```ts\n import { installAssets } from \"@xmcl/installer\";\n import { MinecraftLocation, ResolvedVersion, Version } from \"@xmcl/core\";\n\n const minecraft: MinecraftLocation;\n const version: string; // version string like 1.13\n const resolvedVersion: ResolvedVersion = await Version.parse(minecraft, version);\n await installAssets(resolvedVersion);\n```\n\nJust ensure all assets and libraries are installed:\n\n```ts\n import { installDependencies } from \"@xmcl/installer\";\n import { MinecraftLocation, ResolvedVersion, Version } from \"@xmcl/core\";\n\n const minecraft: MinecraftLocation;\n const version: string; // version string like 1.13\n const resolvedVersion: ResolvedVersion = await Version.parse(minecraft, version);\n await installDependencies(resolvedVersion);\n```\n### Progress Moniting on Installation\n\nMost install function has a corresponding task function. For example, `install` function has the function name `installTask` which is the task version monitor the progress of install.\n\nHere is the example of just moniting the install task overall progress: \n\n```ts\n// suppose you have define such functions to update UI\ndeclare function updateTaskProgress(task: Task<any>, progress: number, total: number): void;\ndeclare function setTaskToFail(task: Task<any>): void;\ndeclare function setTaskToSuccess(task: Task<any>): void;\ndeclare function trackTask(task: Task<any>): void;\n\nconst installAllTask: Task<ResolvedVersion> = installTask(versionMetadata, mcLocation);\nawait installAllTask.startAndWait({\n onStart(task: Task<any>) {\n // a task start\n // task.path show the path\n // task.name is the name\n trackTask(task)\n },\n onUpdate(task: Task<any>, chunkSize: number) {\n // a task update\n // the chunk size usually the buffer size\n // you can use this to track download speed\n\n // you can track this specific task progress\n updateTaskProgress(task, task.progress, task.total);\n\n // or you can update the root task by\n updateTaskProgress(task, installAllTask.progress, installAllTask.total);\n },\n onFailed(task: Task<any>, error: any) {\n // on a task fail\n setTaskToFail(task);\n },\n onSuccessed(task: Task<any>, result: any) {\n // on task success\n setTaskToSuccess(task);\n },\n // on task is paused/resumed/cancelled\n onPaused(task: Task<any>) {\n },\n onResumed(task: Task<any>) {\n },\n onCancelled(task: Task<any>) {\n },\n});\n\n```\n\nThe task is designed to organize the all the works in a tree like structure.\n\nThe `installTask` has such parent/child structure\n\n- install\n - version\n - json\n - jar\n - dependencies\n - assets\n - assetsJson\n - asset\n - libraries\n - library\n\nTo generally display this tree in UI. You can identify the task by its `path`.\n\n```ts\nfunction updateTaskUI(task: Task<any>, progress: number, total: number) {\n // you can use task.path as identifier\n // and update the task on UI\n const path = task.path;\n // the path can be something like `install.version.json`\n}\n```\n\nOr you can use your own identifier like uuid:\n\n```ts\n// you customize function to make task to a user reacable string to display in UI\ndeclare function getTaskName(task: Task<any>): string;\n\nfunction runTask(rootTask: Task<any>) {\n // your own id for this root task\n const uid = uuid();\n await rootTask.startAndWait({\n onStart(task: Task<any>) {\n // tell ui that a task with such name started\n // the task id is a number id from 0\n trackTask(`${uid}.${task.id}`, getTaskName(task));\n },\n onUpdate(task: Task<any>, chunkSize: number) {\n // update the total progress \n updateTaskProgress(`${uid}.${task.id}`, installAllTask.progress, installAllTask.total);\n },\n onStart(task: Task<any>) {\n // tell ui this task ended\n endTask(`${uid}.${task.id}`);\n },\n });\n}\n\n```\n\n### Install Library/Assets with Customized Host\n\nTo swap the library to your self-host or other customized host, you can assign the `libraryHost` field in options.\n\nFor example, if you want to download the library `commons-io:commons-io:2.5` from your self hosted server, you can have\n\n```ts\n // the example for call `installLibraries`\n // this option will also work for other functions involving libraries like `install`, `installDependencies`.\n await installLibraries(resolvedVersion, {\n libraryHost(library: ResolvedLibrary) {\n if (library.name === \"commons-io:commons-io:2.5\") {\n // the downloader will first try the first url in the array\n // if this failed, it will try the 2nd.\n // if it's still failed, it will try original url\n return [\"https://your-host.org/the/path/to/the/jar\", \"your-sencodary-url\"];\n // if you just have one url\n // just return a string here...\n }\n // return undefined if you don't want to change lib url\n return undefined;\n },\n mavenHost: ['https://www.your-other-maven.org'], // you still can use this to add other maven\n });\n\n // it will first try you libraryHost url and then try mavenHost url.\n```\n\nTo swap the assets host, you can just assign the assets host url to the options\n\n```ts\n await installAssets(resolvedVersion, {\n assetsHost: \"https://www.your-url/assets\"\n });\n```\n\nThe assets host should accept the get asset request like `GET https://www.your-url/assets/<hash-head>/<hash>`, where `hash-head` is the first two char in `<hash>`. The `<hash>` is the sha1 of the asset. \n\n### Install Forge\n\nGet the forge version info and install forge from it. \n\n```ts\n import { installForge, getForgeVersionList, ForgeVersionList, ForgeVersion } from \"@xmcl/installer\";\n import { MinecraftLocation } from \"@xmcl/core\";\n \n const list: ForgeVersionList = await getForgeVersionList();\n const minecraftLocation: MinecraftLocation;\n const mcversion = page.mcversion; // mc version\n const firstVersionOnPage: ForgeVersion = page.versions[0];\n await installForge(firstVersionOnPage, minecraftLocation);\n```\n\nIf you know forge version and minecraft version. You can directly do such:\n\n```ts\n import { installForge } from \"@xmcl/installer\";\n \n const forgeVersion = 'a-forge-version'; // like 31.1.27\n await installForge({ version: forgeVersion, mcversion: '1.15.2' }, minecraftLocation);\n```\n\nNotice that this installation doesn't ensure full libraries installation.\nPlease run `installDependencies` afther that.\n\nThe new 1.13 forge installation process requires java to run. \nEither you have `java` executable in your environment variable PATH,\nor you can assign java location by `installForge(forgeVersionMeta, minecraftLocation, { java: yourJavaExecutablePath });`.\n\nIf you use this auto installation process to install forge, please checkout [Lex's Patreon](https://www.patreon.com/LexManos).\nConsider support him to maintains forge.\n\n### Install Fabric\n\nFetch the new fabric version list.\n\n```ts\n import { installFabric, FabricArtifactVersion } from \"@xmcl/installer\";\n\n const versionList: FabricArtifactVersion[] = await getFabricArtifactList();\n```\n\nInstall fabric to the client. This installation process doesn't ensure the minecraft libraries.\n\n```ts\n const minecraftLocation: MinecraftLocation;\n await installFabric(versionList[0], minecraftLocation);\n```\n\nPlease run `Installer.installDependencies` after that to install fully.\n\n## New Forge Installing process\n\nThe module have three stage for installing new forge *(mcversion >= 1.13)*\n\n1. Deploy forge installer jar\n 1. Download installer jar\n 2. Extract forge universal jar files in installer jar into `.minecraft/libraries`\n 3. Extract `version.json` into target version folder, `.minecraft/versions/<ver>/<ver>.json`\n 4. Extract `installer_profile.json` into target version folder, `.minecraft/versions/<ver>/installer_profile.json`\n2. Download Dependencies\n 1. Merge libraires in `installer_profile.json` and `<ver>.json`\n 2. Download them\n3. Post processing forge jar\n 1. Parse `installer_profile.json`\n 2. Get the processors info and execute all of them.\n\nThe `installForge` will do all of them.\n\nThe `installByProfile` will do 2 and 3.\n\n### Install Java 8 From Mojang Source\n\nScan java installation path from the disk. (Require a lzma unpacker, like [7zip-bin](https://www.npmjs.com/package/7zip-bin) or [lzma-native](https://www.npmjs.com/package/lzma-native))\n\n```ts\n import { installJreFromMojang } from \"@xmcl/installer\";\n\n // this require a unpackLZMA util to work\n // you can use `7zip-bin`\n // or `lzma-native` for this\n const unpackLZMA: (src: string, dest: string) => Promise<void>;\n\n await installJreFromMojang({\n destination: \"your/java/home\",\n unpackLZMA,\n });\n```\n"
46}
\No newline at end of file