mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 05:50:39 +00:00
83 lines
4.6 KiB
JavaScript
83 lines
4.6 KiB
JavaScript
import { createHash } from 'node:crypto'
|
|
import { readFile, writeFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
|
|
const worlds = [
|
|
{ name: 'seed-selection-default', seed: '1337', argument: '' },
|
|
{ name: 'seed-selection-positive', seed: '78264193', argument: ' seed=78264193' },
|
|
{ name: 'seed-selection-negative', seed: '-734829104958217364', argument: ' seed=-734829104958217364' },
|
|
{ name: 'seed-selection-zero', seed: '0', argument: ' seed=0' }
|
|
]
|
|
|
|
export default {
|
|
name: 'iris-seed-selection',
|
|
description: 'Verify omitted, positive, negative, and zero creation seeds against visible terrain and a cold restart.',
|
|
async run(context) {
|
|
const source = await readFile(path.join(context.server.directory, '.server-source'), 'utf8')
|
|
context.expect(/^isolated=true\s*$/m.test(source), 'Seed selection requires an isolated instance')
|
|
const wait = (predicate, label) => context.waitUntil(predicate, { label, timeoutMs: 60000, intervalMs: 100 })
|
|
const restart = context.options.command === 'restart-check'
|
|
const stateFile = path.join(context.server.directory, '.seed-selection.json')
|
|
const saved = restart ? JSON.parse(await readFile(stateFile, 'utf8')) : undefined
|
|
const jarHash = createHash('sha256').update(await readFile(path.join(context.server.directory, 'plugins', 'Iris.jar'))).digest('hex')
|
|
const processId = (await context.observe()).processId
|
|
if (restart) {
|
|
context.expect(saved.processId !== processId, 'Restart-check requires a cold server restart')
|
|
context.expect(saved.jarHash === jarHash, 'Restart-check requires the same Iris jar')
|
|
}
|
|
const outputs = {}
|
|
for (const world of worlds) {
|
|
await context.step(`${restart ? 'Reload' : 'Create'} ${world.name} with seed ${world.seed}`, async () => {
|
|
if (!restart) {
|
|
await context.command(`/iris create name=${world.name} type=cohesion${world.argument}`,
|
|
/Successfully created your world/i, 180000)
|
|
}
|
|
await context.command(`/iris tp ${world.name}`)
|
|
await wait(async () => {
|
|
const observation = await context.observe()
|
|
const player = observation.players.find(entry => entry.username === context.bot.username)
|
|
const current = observation.worlds.find(entry => entry.id === player?.world)
|
|
return current?.key === `iris:${world.name}` || current?.name.endsWith(world.name)
|
|
}, `Enter ${world.name}`)
|
|
await context.command('/minecraft:gamemode spectator @s')
|
|
await wait(() => context.bot.game.gameMode === 'spectator', 'Spectator mode')
|
|
await context.command('/minecraft:seed', new RegExp(`Seed:\\s*\\[?${world.seed}\\]?(?:\\s|$)`))
|
|
const x = 1024
|
|
const z = -1024
|
|
await context.command(`/minecraft:tp @s ${x + 8.5} 48 ${z + 8.5}`, /Teleported/i, 30000)
|
|
await wait(() => Math.abs(context.bot.entity.position.x - x - 8.5) < 1
|
|
&& Math.abs(context.bot.entity.position.z - z - 8.5) < 1, 'Sample teleport')
|
|
const position = context.bot.entity.position.clone()
|
|
await wait(() => context.bot.blockAt(position.clone().set(x, 0, z))
|
|
&& context.bot.blockAt(position.clone().set(x + 15, 63, z + 15)), 'Complete sample chunk')
|
|
const digest = createHash('sha256')
|
|
let stone = 0
|
|
for (let dx = 0; dx < 16; dx++) {
|
|
for (let dz = 0; dz < 16; dz++) {
|
|
for (let y = 0; y < 64; y++) {
|
|
const block = context.bot.blockAt(position.set(x + dx, y, z + dz))
|
|
context.expect(block !== null, 'Missing sampled block', { x: x + dx, y, z: z + dz })
|
|
digest.update(`${block.stateId},`)
|
|
if (block.name === 'stone') stone++
|
|
}
|
|
}
|
|
}
|
|
context.expect(stone > 1000, 'Fixture terrain was not generated', { world: world.name, stone })
|
|
const blocks = digest.digest('hex')
|
|
outputs[world.name] = { seed: world.seed, blocks }
|
|
if (restart) {
|
|
context.expect(saved.worlds[world.name].seed === world.seed, 'Seed expectation changed after restart')
|
|
context.expect(saved.worlds[world.name].blocks === blocks, 'Persisted terrain changed after restart',
|
|
{ world: world.name, before: saved.worlds[world.name].blocks, after: blocks })
|
|
}
|
|
})
|
|
}
|
|
const signatures = new Set(Object.values(outputs).map(output => output.blocks))
|
|
context.expect(signatures.size === worlds.length, 'Different requested seeds generated identical sample chunks', outputs)
|
|
context.report.seedSelection = { restart, jarHash, worlds: outputs }
|
|
if (!restart) {
|
|
await writeFile(stateFile, JSON.stringify({ processId, jarHash, worlds: outputs }))
|
|
}
|
|
}
|
|
}
|