From 74c3b69a418fee1c419b23c6f618e1d3a7a1cc14 Mon Sep 17 00:00:00 2001 From: Pierce Date: Sun, 28 Aug 2022 21:59:32 -0700 Subject: [PATCH] Properly parse object based launch args Closes #90 --- README.md | 15 ++++++------ components/handler.js | 54 +++++++++++++++++++++++++++++++++++++------ index.d.ts | 4 ++++ package.json | 2 +- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4d7737e..463a209 100644 --- a/README.md +++ b/README.md @@ -61,18 +61,19 @@ launcher.on('data', (e) => console.log(e)); | Parameter | Type | Description | Required | |--------------------------|----------|-------------------------------------------------------------------------------------------|----------| | `options.clientPackage` | String | Path or URL to the client package zip file. Do not rehost Minecraft, it's against ToS. | False | -| `options.removePackage` | Boolean | Option to remove the client package zip file after its finished extracting. | False | +| `options.removePackage` | Boolean | Option to remove the client package zip file after its finished extracting. | False | | `options.installer` | String | Path to installer being executed. | False | | `options.root` | String | Path where you want the launcher to work in. like `C:/Users/user/AppData/Roaming/.mc`, | True | | `options.os` | String | windows, osx or linux. MCLC will auto determine the OS if this field isn't provided. | False | -| `options.customLaunchArgs`| Array | Array of custom Minecraft arguments you want to add. | False | +| `options.customLaunchArgs`| Array | Array of custom Minecraft arguments you want to add. | False | | `options.customArgs` | Array | Array of custom Java arguments you want to add. | False | +| `options.features` | Array | Array of game argument feature flags. ex: `is_demo_user` or `has_custom_resolution` | False | | `options.version.number` | String | Minecraft version that is going to be launched. | True | | `options.version.type` | String | Any string. The actual Minecraft launcher uses `release` and `snapshot`. | True | | `options.version.custom` | String | The name of the folder, jar file, and version json in the version folder. | False | | `options.memory.max` | String | Max amount of memory being used by Minecraft. | True | | `options.memory.min` | String | Min amount of memory being used by Minecraft. | True | -| `options.forge` | String | Path to Forge Jar. (Versions below 1.13 should be the "universal" jar while versions above 1.13+ should be the "installer" jar)| False | +| `options.forge` | String | Path to Forge Jar. (Versions below 1.13 should be the "universal" jar while versions above 1.13+ should be the "installer" jar) | False | | `options.javaPath` | String | Path to the JRE executable file, will default to `java` if not entered. | False | | `options.server.host` | String | Host url to the server, don't include the port. | False | | `options.server.port` | String | Port of the host url, will default to `25565` if not entered. | False | @@ -81,9 +82,9 @@ launcher.on('data', (e) => console.log(e)); | `options.proxy.username` | String | Username for the proxy. | False | | `options.proxy.password` | String | Password for the proxy. | False | | `options.timeout` | Integer | Timeout on download requests. | False | -| `options.window.width` | String | Width of the Minecraft Client | False | +| `options.window.width` | String | Width of the Minecraft Client. | False | | `options.window.height` | String | Height of the Minecraft Client. | False | -| `options.window.fullscreen` | Boolean| Fullscreen the Minecraft Client. | False | +| `options.window.fullscreen` | Boolean| Fullscreen the Minecraft Client. | False | | `options.overrides` | Object | Json object redefining paths for better customization. Example below. | False | #### IF YOU'RE NEW TO MCLC, LET IT HANDLE EVERYTHING! DO NOT USE OVERRIDES! ```js @@ -130,7 +131,7 @@ If you are loading up a client outside of vanilla Minecraft or Forge (Optifine a ##### Installer This runs an executable with specified launch arguments. Was used to support Forge 1.13 before ForgeWrapper. ##### Authentication -MCLC's authenticator module does not support Microsoft authentication. You will need to use a library like [MSMC](https://github.com/Hanro50/MSMC). If you weant to create your own solution, the following is the authorization JSON object format. +MCLC's authenticator module does not support Microsoft authentication. You will need to use a library like [MSMC](https://github.com/Hanro50/MSMC). If you want to create your own solution, the following is the authorization JSON object format. ```js { access_token: '', @@ -140,7 +141,7 @@ MCLC's authenticator module does not support Microsoft authentication. You will user_properties: '{}', meta: { type: 'mojang' || 'msa', - demo: true || false, + demo: true || false, // Demo can also be specified by addomg 'is_demo_user' to the options.feature array // properties only exists for specific Minecraft versions. xuid: '', clientId: '' diff --git a/components/handler.js b/components/handler.js index 26e2f15..7c45463 100644 --- a/components/handler.js +++ b/components/handler.js @@ -557,6 +557,7 @@ class Handler { const minArgs = this.options.overrides.minArgs || this.isLegacy() ? 5 : 11 if (args.length < minArgs) args = args.concat(this.version.minecraftArguments ? this.version.minecraftArguments.split(' ') : this.version.arguments.game) + if (this.options.customLaunchArgs) args = args.concat(this.options.customLaunchArgs) this.options.authorization = await Promise.resolve(this.options.authorization) this.options.authorization.meta = this.options.authorization.meta ? this.options.authorization.meta : { type: 'mojang' } @@ -574,24 +575,63 @@ class Handler { '${assets_root}': assetPath, '${game_assets}': assetPath, '${version_type}': this.options.version.type, - '${clientid}': this.options.authorization.meta.clientId || (this.options.authorization.client_token || this.options.authorization.access_token) + '${clientid}': this.options.authorization.meta.clientId || (this.options.authorization.client_token || this.options.authorization.access_token), + '${resolution_width}' : this.options.window ? this.options.window.width : 856, + '${resolution_height}': this.options.window ? this.options.window.height : 482, } - if (this.options.authorization.meta.demo) { + if (this.options.authorization.meta.demo && (this.options.features ? !this.options.features.includes('is_demo_user') : true)) { args.push('--demo') } + const replaceArg = (obj, index) => { + if (Array.isArray(obj.value)) { + for (const arg of obj.value) { + console.log(arg) + args.push(arg) + } + } else { + args.push(obj.value) + } + delete args[index] + } + for (let index = 0; index < args.length; index++) { - if (typeof args[index] === 'object') args.splice(index, 2) - if (Object.keys(fields).includes(args[index])) { - args[index] = fields[args[index]] + if (typeof args[index] === 'object') { + if (args[index].rules) { + if (!this.options.features) continue + const featureFlags = [] + for (const rule of args[index].rules) { + featureFlags.push(...Object.keys(rule.features)) + } + let hasAllRules = true + for (const feature of this.options.features) { + if (!featureFlags.includes(feature)) { + hasAllRules = false + } + } + if (hasAllRules) replaceArg(args[index], index) + } else { + replaceArg(args[index], index) + } + } else { + if (Object.keys(fields).includes(args[index])) { + args[index] = fields[args[index]] + } } } + args = args.filter((value) => { + return typeof value === 'string' || typeof value === 'number' + }) if (this.options.window) { this.options.window.fullscreen ? args.push('--fullscreen') - : args.push('--width', this.options.window.width, '--height', this.options.window.height) + : () => { + if (this.options.features ? !this.options.features.includes('has_custom_resolution') : true) { + args.push('--width', this.options.window.width, '--height', this.options.window.height) + } + } } if (this.options.server) args.push('--server', this.options.server.host, '--port', this.options.server.port || '25565') if (this.options.proxy) { @@ -606,7 +646,7 @@ class Handler { this.options.proxy.password ) } - if (this.options.customLaunchArgs) args = args.concat(this.options.customLaunchArgs) + this.client.emit('debug', '[MCLC]: Set launch options') return args } diff --git a/index.d.ts b/index.d.ts index a6cc2e2..95431ab 100644 --- a/index.d.ts +++ b/index.d.ts @@ -62,6 +62,10 @@ declare module "minecraft-launcher-core" { * Array of custom Java arguments */ customArgs?: Array; + /** + * Array of game argument feature flags + */ + features?: Array; /** * minecraft version info */ diff --git a/package.json b/package.json index e9605c4..a1846ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecraft-launcher-core", - "version": "3.16.14", + "version": "3.16.15", "description": "Lightweight module that downloads and runs Minecraft using javascript / NodeJS", "main": "index.js", "dependencies": {