Skip to content
Closed
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
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ jobs:
with:
java-version: 17
java-package: jre
# Old versions of bedrock use old libssl that Ubuntu no longer ships with; need manual install
- name: (Linux) Install libssl 1.1
if: runner.os == 'Linux'
run: |
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
- run: npm install
- run: npm test
5 changes: 4 additions & 1 deletion lib/bedrock/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ module.exports = (data) => {

return {
handleStartGame (packet) {
loadItemStates(packet.itemstates)
if (packet.itemstates != null) {
loadItemStates(packet.itemstates)
}

if (this.supportFeature('blockHashes') && packet.block_network_ids_are_hashes) {
loadHashedRuntimeIds(this)
} else {
Expand Down
17 changes: 9 additions & 8 deletions test/mcbedrock.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ async function main (version = '1.19.63') {
console.log('Loading item palette and custom blocks')
registry.handleStartGame(params)

console.log('Loaded item palette', registry.items)
if (params.itemstates != null) {
console.log('Loaded item palette')

const reEncoded = registry.writeItemStates()
assert.deepEqual(
reEncoded.sort((a, b) => a.runtime_id - b.runtime_id),
params.itemstates.sort((a, b) => a.runtime_id - b.runtime_id)
)
console.log('Re-encoded item palette')
const reEncoded = registry.writeItemStates()
assert.deepEqual(
reEncoded.sort((a, b) => a.runtime_id - b.runtime_id),
params.itemstates.sort((a, b) => a.runtime_id - b.runtime_id)
)
console.log('Re-encoded item palette')
}

loggedIn = true
}
}

await collectPackets(version, Object.keys(handlers), (name, params) => handlers[name](version, params))
await new Promise((resolve) => setTimeout(resolve, 30000))
if (!loggedIn) {
throw new Error('Did not login')
}
Expand Down
12 changes: 8 additions & 4 deletions test/mcbedrock.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/* eslint-env mocha */

const SUPPORTED_VERSIONS = ['1.17.10', '1.18.0', '1.18.11', '1.18.30', '1.19.1', '1.19.10']
const SUPPORTED_VERSIONS = ['1.17.10', '1.18.0', '1.18.11', '1.18.30', '1.19.1', '1.19.10', '1.21.70']
const test = require('./mcbedrock')
const { sleep } = require('./util/sleep')

describe('mcbedrock', function () {
this.timeout(18000 * 10)
const vcount = SUPPORTED_VERSIONS.length
this.timeout(vcount * 80 * 1000)

for (const version of SUPPORTED_VERSIONS) {
// skipped bedrock because it times out; fix in https://github.com/PrismarineJS/prismarine-registry/issues/43
it.skip('works on ' + version, () => test(version))
it('works on ' + version, async () => {
await test(version)
await sleep(100)
})
}
})
83 changes: 54 additions & 29 deletions test/util/collectBedrockPackets.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,77 @@
const bedrock = require('bedrock-protocol')
const { startServer } = require('minecraft-bedrock-server')
const { startServerAndWait2 } = require('minecraft-bedrock-server')
const debug = require('debug')('prismarine-registry')
const path = require('path')
const { getPort } = require('./getPort')
const { waitFor } = require('./waitFor')
const { sleep } = require('./sleep')

async function collectPackets (version, names = ['start_game'], cb) {
const collected = []
const server = await new Promise((resolve) => {
const server = startServer(version, () => resolve(server), {
'online-mode': false,
'server-port': 19130,
path: path.join(__dirname, `server_bedrock_${version}`)
})
const [port, v6] = [await getPort(), await getPort()]
console.log('Starting vanilla server', version, 'on port', port, v6)
const server = await startServerAndWait2(version, 1000 * 220, {
'online-mode': false,
'server-port': port,
'server-portv6': v6,
path: path.join(__dirname, `server_bedrock_${version}`)
})
console.log('Started server')

console.log('Started server', version)
await sleep(200)

const client = bedrock.createClient({
version,
host: '127.0.0.1',
port: 19130,
port,
username: 'test',
offline: true
version,
raknetBackend: 'raknet-native',
offline: true,
skipPing: true
})

console.log('Started client. Connecting to server')

let clientConnected = false
const collected = []
await waitFor((resolve) => {
client.on('join', () => {
console.log('[client] Client connected')
clientConnected = true
stopIfDone()
})

client.on('join', () => {
console.log('[client] Client connected')
clientConnected = true
})
client.on('packet', ({ name }) => debug('[client] -> ', name))

for (const name of names) {
client.on(name, (packet) => {
cb(name, packet)
collected.push(packet)
client.on('error', (err) => {
console.error('[client]', err)
resolve('timeout')
})
}
client.on('end', () => console.log('Bot disconnected.'))

client.on('packet', ({ name }) => debug('[client] -> ', name))
for (const name of names) {
client.on(name, (packet) => {
cb(name, packet)
collected.push(packet)
stopIfDone()
})
}

setTimeout(() => {
console.log('Stopping server', version)
server.kill()
client.close()
if (!clientConnected) {
throw new Error('Client never connected')
function stopIfDone () {
if (clientConnected && collected.length === names.length) {
console.log('✔ Got all packets')
console.log('Stopping server', version)
server.kill()
client.close()
resolve()
}
}
}, 9000)
}, 1000 * 60, () => {
client.close()
server.kill()
throw Error('❌ client timed out ')
})

console.log('Stopping server', version)
}

module.exports = collectPackets
17 changes: 17 additions & 0 deletions test/util/getPort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const net = require('net')

const getPort = () => new Promise(resolve => {
const server = net.createServer()
server.listen(0, '127.0.0.1')
server.on('listening', () => {
const { port } = server.address()
server.close(() => {
// Wait a bit for port to free as we try to bind right after freeing it
setTimeout(() => {
resolve(port)
}, 200)
})
})
})

module.exports = { getPort }
5 changes: 5 additions & 0 deletions test/util/sleep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function sleep (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}

module.exports = { sleep }
12 changes: 12 additions & 0 deletions test/util/waitFor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
async function waitFor (cb, withTimeout, onTimeout) {
let t
const ret = await Promise.race([
new Promise((resolve, reject) => cb(resolve, reject)),
new Promise(resolve => { t = setTimeout(() => resolve('timeout'), withTimeout) })
])
clearTimeout(t)
if (ret === 'timeout') await onTimeout()
return ret
}

module.exports = { waitFor }
Loading