Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,41 @@ Detach from the parent process. So your launcher's exit/crash won't affact the M
```ts
const proc: Promise<ChildProcess> = Launcher.launch({ gamePath, javaPath, version, extraExecOption: { detached: true } });
```

#### Launching with Server Connection

For newer Minecraft versions, use the `quickPlayMultiplayer` option to directly connect to a server:

```ts
import { launch, createQuickPlayMultiplayer } from "@xmcl/core"

// Option 1: Use quickPlayMultiplayer directly
const proc = launch({
gamePath,
javaPath,
version,
quickPlayMultiplayer: 'play.hypixel.net:25565'
});

// Option 2: Use helper function
const proc = launch({
gamePath,
javaPath,
version,
quickPlayMultiplayer: createQuickPlayMultiplayer('mc.example.com', 8080)
});
```

For backward compatibility, the legacy `server` option is still supported:

```ts
// Legacy server option (still works)
const proc = launch({
gamePath,
javaPath,
version,
server: { ip: 'play.hypixel.net', port: 25565 }
});
```

**Note:** When both `quickPlayMultiplayer` and `server` options are provided, `quickPlayMultiplayer` takes precedence.
45 changes: 44 additions & 1 deletion packages/core/launch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import assert from 'assert'
import { spawnSync } from 'child_process'
import { EOL } from 'os'
import * as path from 'path'
import { DEFAULT_EXTRA_JVM_ARGS, generateArguments, generateArgumentsServer } from './launch'
import { DEFAULT_EXTRA_JVM_ARGS, generateArguments, generateArgumentsServer, createQuickPlayMultiplayer } from './launch'
import { describe, test, expect } from 'vitest'

function getJavaVersion(javaPath: string) {
Expand Down Expand Up @@ -281,5 +281,48 @@ describe('Launcher', () => {
expect(args[args.indexOf('--server') + 1]).toEqual(server.ip)
expect(args[args.indexOf('--port') + 1]).toEqual(server.port.toString())
})
test('should generate correct command with quickPlayMultiplayer', async ({ mock }) => {
const args = await generateArguments({
version: '1.14.4', gamePath: mock, javaPath: '/test/java', quickPlayMultiplayer: '127.0.0.1:25565',
})
expect(args[args.indexOf('--quickPlayMultiplayer') + 1]).toEqual('127.0.0.1:25565')
// Should not contain old server arguments
expect(args.indexOf('--server')).toBe(-1)
expect(args.indexOf('--port')).toBe(-1)
})
test('should prefer quickPlayMultiplayer over server option', async ({ mock }) => {
const server = {
ip: '192.168.1.1',
port: 25565,
}
const args = await generateArguments({
version: '1.14.4',
gamePath: mock,
javaPath: '/test/java',
server,
quickPlayMultiplayer: '127.0.0.1:25565',
})
expect(args[args.indexOf('--quickPlayMultiplayer') + 1]).toEqual('127.0.0.1:25565')
// Should not contain old server arguments when quickPlayMultiplayer is present
expect(args.indexOf('--server')).toBe(-1)
expect(args.indexOf('--port')).toBe(-1)
})
})

describe('#createQuickPlayMultiplayer', () => {
test('should create quickPlayMultiplayer string with IP only', () => {
const result = createQuickPlayMultiplayer('127.0.0.1')
expect(result).toEqual('127.0.0.1')
})

test('should create quickPlayMultiplayer string with IP and port', () => {
const result = createQuickPlayMultiplayer('127.0.0.1', 25565)
expect(result).toEqual('127.0.0.1:25565')
})

test('should create quickPlayMultiplayer string with custom port', () => {
const result = createQuickPlayMultiplayer('play.example.com', 8080)
expect(result).toEqual('play.example.com:8080')
})
})
})
19 changes: 18 additions & 1 deletion packages/core/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ export interface LaunchOption {
* Directly launch to a server
*/
server?: { ip: string; port?: number }
/**
* Directly launch to a server using quickPlayMultiplayer option (for newer Minecraft versions)
* This will use --quickPlayMultiplayer instead of --server and --port
*/
quickPlayMultiplayer?: string
/**
* Resolution. This will add --height & --width or --fullscreen to the java arguments
*/
Expand Down Expand Up @@ -805,7 +810,9 @@ export async function generateArguments(options: LaunchOption) {
if (options.extraMCArgs) {
cmd.push(...options.extraMCArgs)
}
if (options.server) {
if (options.quickPlayMultiplayer) {
cmd.push('--quickPlayMultiplayer', options.quickPlayMultiplayer)
} else if (options.server) {
cmd.push('--server', options.server.ip)
if (options.server.port) {
cmd.push('--port', options.server.port.toString())
Expand Down Expand Up @@ -854,3 +861,13 @@ function normalizeArguments(args: Version.LaunchArgument[], platform: Platform,
return result
}, [])
}

/**
* Create a quickPlayMultiplayer string from server IP and optional port
* @param ip The server IP address
* @param port The server port (optional, defaults to 25565 if not specified)
* @returns A formatted string for quickPlayMultiplayer option
*/
export function createQuickPlayMultiplayer(ip: string, port?: number): string {
return port ? `${ip}:${port}` : ip
}
17 changes: 9 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading