Properly parse object based launch args

Closes #90
This commit is contained in:
Pierce 2022-08-28 21:59:32 -07:00
parent 61e4c666db
commit 74c3b69a41
4 changed files with 60 additions and 15 deletions

View file

@ -67,12 +67,13 @@ launcher.on('data', (e) => console.log(e));
| `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.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,7 +82,7 @@ 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.overrides` | Object | Json object redefining paths for better customization. Example below. | False |
@ -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: ''

View file

@ -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 (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
}

4
index.d.ts vendored
View file

@ -62,6 +62,10 @@ declare module "minecraft-launcher-core" {
* Array of custom Java arguments
*/
customArgs?: Array<string>;
/**
* Array of game argument feature flags
*/
features?: Array<string>;
/**
* minecraft version info
*/

View file

@ -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": {