merge: preserve ShaCraft 0.1.1 account and Windows features in modular launcher
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { equal } from 'node:assert/strict'
|
||||
import { test } from 'node:test'
|
||||
import { launchAccess, linkedNickname, validCredentials } from './account.ts'
|
||||
|
||||
test('launch requires a restored ShaCraft account and its verified Aeronautics link', () => {
|
||||
equal(launchAccess(undefined), 'loading')
|
||||
equal(launchAccess(null), 'login')
|
||||
equal(launchAccess({ username: 'account', links: [] }), 'link')
|
||||
equal(launchAccess({ username: 'account', links: [{ server_id: 'create', mc_username: 'Other_Name' }] }), 'link')
|
||||
equal(launchAccess({ username: 'account', links: [{ server_id: 'aoc', mc_username: 'Verified_Name' }] }), 'ready')
|
||||
})
|
||||
|
||||
test('identity uses snake-case account link payload and never the account login', () => {
|
||||
const account = { username: 'Local_Login', links: [
|
||||
{ server_id: 'create', mc_username: 'Other_Name' },
|
||||
{ server_id: 'aoc', mc_username: 'Verified_Name' },
|
||||
] }
|
||||
equal(linkedNickname(account), 'Verified_Name')
|
||||
equal(linkedNickname({ username: 'Valid_Login', links: [] }), null)
|
||||
equal(linkedNickname({ username: 'Valid_Login', links: [{ server_id: 'aoc', mc_username: '../unsafe' }] }), null)
|
||||
})
|
||||
|
||||
test('ShaCraft credentials preserve the server 3–32 login and 3–128 password contract', () => {
|
||||
equal(validCredentials('abc', '123'), true)
|
||||
equal(validCredentials('a'.repeat(32), 'p'.repeat(128)), true)
|
||||
equal(validCredentials('ab', '123'), false)
|
||||
equal(validCredentials('a'.repeat(33), '123'), false)
|
||||
equal(validCredentials('неверно', '123'), false)
|
||||
equal(validCredentials('account', '12'), false)
|
||||
equal(validCredentials('account', 'p'.repeat(129)), false)
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { ShaCraftAccount } from '../types/launcher'
|
||||
import { isValidNickname } from './settings'
|
||||
|
||||
/** Only the authenticated account's verified Aeronautics link selects a name. */
|
||||
export function linkedNickname(account: ShaCraftAccount | null | undefined): string | null {
|
||||
const nickname = account?.links.find((link) => link.server_id === 'aoc')?.mc_username
|
||||
return nickname && isValidNickname(nickname) ? nickname : null
|
||||
}
|
||||
|
||||
export function launchAccess(account: ShaCraftAccount | null | undefined) {
|
||||
if (account === undefined) return 'loading'
|
||||
if (account === null) return 'login'
|
||||
return linkedNickname(account) ? 'ready' : 'link'
|
||||
}
|
||||
|
||||
export function validCredentials(username: string, password: string): boolean {
|
||||
return /^[A-Za-z0-9_]{3,32}$/.test(username) && password.length >= 3 && password.length <= 128
|
||||
}
|
||||
@@ -14,6 +14,17 @@ test('installation, running game and exit have distinct states', () => {
|
||||
deepStrictEqual(gameReducer(running, { type: 'exited', result: { profileId, exitCode: 0 } }), initialGameState)
|
||||
})
|
||||
|
||||
test('every launch can reconcile the modpack before installation and process spawn', () => {
|
||||
const syncing = gameReducer(initialGameState, { type: 'sync', profileId })
|
||||
equal(syncing.operation.phase, 'syncing')
|
||||
const synced = gameReducer(syncing, { type: 'synced', profileId })
|
||||
const installingAfterSync = gameReducer(synced, { type: 'install', profileId })
|
||||
equal(installingAfterSync.operation.phase, 'installing')
|
||||
const launchingAfterInstall = gameReducer(installingAfterSync, { type: 'launch', profileId })
|
||||
equal(launchingAfterInstall.operation.phase, 'launching')
|
||||
equal(gameReducer(launchingAfterInstall, { type: 'started', profileId }).operation.phase, 'running')
|
||||
})
|
||||
|
||||
test('a fast child exit cannot be overwritten by a late launch acknowledgement', () => {
|
||||
const exited = gameReducer(launching, { type: 'exited', result: { profileId, exitCode: 1 } })
|
||||
const lateAcknowledgement = gameReducer(exited, { type: 'started', profileId })
|
||||
|
||||
Reference in New Issue
Block a user