Skip to content

Add dimensionChange event #3275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 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 docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,12 @@ comparison.

Note that `oldBlock` may be `null`.

#### "dimensionChange" (dimension)

Emitted after the dimension the bot is in has changed.

* `dimension` - The dimension that was switched to

#### "blockPlaced" (oldBlock, newBlock)

Fires when bot places block. Both `oldBlock` and `newBlock` provided for
Expand Down
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export interface BotEvents {
playerLeft: (entity: Player) => Promise<void> | void
blockUpdate: (oldBlock: Block | null, newBlock: Block) => Promise<void> | void
'blockUpdate:(x, y, z)': (oldBlock: Block | null, newBlock: Block | null) => Promise<void> | void
dimensionChange: (dimension: Dimension) => Promise<void> | void
chunkColumnLoad: (entity: Vec3) => Promise<void> | void
chunkColumnUnload: (entity: Vec3) => Promise<void> | void
soundEffectHeard: (
Expand Down
10 changes: 6 additions & 4 deletions lib/plugins/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const paintingFaceToVec = [
new Vec3(1, 0, 0)
]

const dimensionNames = {
'-1': 'minecraft:nether',
const dimensionIdentifiers = {
'-1': 'minecraft:the_nether',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure its the_nether and not world_nether?

0: 'minecraft:overworld',
1: 'minecraft:end'
1: 'minecraft:the_end'
}

function inject (bot, { version, storageBuilder, hideErrors }) {
Expand Down Expand Up @@ -468,7 +468,7 @@ function inject (bot, { version, storageBuilder, hideErrors }) {
let worldName
function dimensionToFolderName (dimension) {
if (bot.supportFeature('dimensionIsAnInt')) {
return dimensionNames[dimension]
return dimensionIdentifiers[dimension]
} else if (bot.supportFeature('dimensionIsAString') || bot.supportFeature('dimensionIsAWorld')) {
return worldName
}
Expand Down Expand Up @@ -500,6 +500,7 @@ function inject (bot, { version, storageBuilder, hideErrors }) {
bot.world = new World(null, storageBuilder ? storageBuilder({ version: bot.version, worldName: dimensionToFolderName(dimension) }) : null).sync
startListenerProxy()
}
bot.emit('dimensionChange', worldName.replace('minecraft:', ''))
}

bot._client.on('login', (packet) => {
Expand All @@ -517,6 +518,7 @@ function inject (bot, { version, storageBuilder, hideErrors }) {
if (bot.supportFeature('dimensionIsAnInt')) { // <=1.15.2
if (dimension === packet.dimension) return
dimension = packet.dimension
worldName = dimensionToFolderName(dimension)
} else { // >= 1.15.2
if (dimension === packet.dimension) return
if (worldName === packet.worldName && packet.copyMetadata === true) return // don't unload chunks if in same world and metaData is true
Expand Down
131 changes: 88 additions & 43 deletions test/externalTests/nether.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,97 @@
const assert = require('assert')
const Vec3 = require('vec3')
const { once } = require('events')
const { onceWithCleanup, sleep } = require('../../lib/promise_utils')
const Vec3Parser = require('vec3')
const { Vec3 } = require('vec3')

module.exports = () => async (bot) => {
// Test spawn event on death
const Item = require('prismarine-item')(bot.registry)
module.exports = (version) => {
async function runTest (bot, testFunction) {
await testFunction(bot)
}

const tests = []

let signItem = null
for (const name in bot.registry.itemsByName) {
if (name.includes('sign') && !name.includes('hanging')) signItem = bot.registry.itemsByName[name]
function addTest (name, f) {
tests[name] = bot => runTest(bot, f)
}
assert.notStrictEqual(signItem, null)

const p = new Promise((resolve, reject) => {
bot._client.on('open_sign_entity', (packet) => {
const sign = bot.blockAt(new Vec3(packet.location))
bot.updateSign(sign, '1\n2\n3\n')

setTimeout(() => {
// Get updated sign
const sign = bot.blockAt(bot.entity.position)

assert.strictEqual(sign.signText.trimEnd(), '1\n2\n3')

if (sign.blockEntity) {
// Check block update
bot.activateBlock(sign)
assert.notStrictEqual(sign.blockEntity, undefined)
}

bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
once(bot, 'spawn').then(resolve)
}, 500)
})

addTest('spawn event on death and nether sign', async (bot) => {
// Test spawn event on death
const Item = require('prismarine-item')(bot.registry)

let signItem = null
for (const name in bot.registry.itemsByName) {
if (name.includes('sign') && !name.includes('hanging')) signItem = bot.registry.itemsByName[name]
}
assert.notStrictEqual(signItem, null, 'Could not find sign item')

await bot.waitForChunksToLoad()
bot.test.sayEverywhere('/setblock ~2 ~ ~ nether_portal')
bot.test.sayEverywhere('/setblock ~2 ~ ~ portal')
bot.test.sayEverywhere('/tp ~2 ~ ~')
await onceWithCleanup(bot, 'spawn')

await bot.test.resetNetherRoofToBedrock()
bot.test.sayEverywhere('/tp ~ 128 ~')
await onceWithCleanup(bot, 'forcedMove')
await bot.waitForChunksToLoad()

const lowerBlock = bot.blockAt(bot.entity.position.offset(0, -1, 0))
await bot.lookAt(lowerBlock.position.offset(0.5, 0.5, 0.5), true)

await bot.test.setInventorySlot(36, new Item(signItem.id, 1, 0))
bot.placeBlock(lowerBlock, new Vec3(0, 1, 0)).catch(err => assert.rejects(err))

const [packet] = await onceWithCleanup(bot._client, 'open_sign_entity')

const sign = bot.blockAt(Vec3Parser(packet.location))
bot.updateSign(sign, '1\n2\n3\n')

await sleep(500)
// Get updated sign
const newSign = bot.blockAt(bot.entity.position)

assert.strictEqual(newSign.signText.trimEnd(), '1\n2\n3')

if (newSign.blockEntity) {
// Check block update
bot.activateBlock(newSign)
assert.notStrictEqual(newSign.blockEntity, undefined)
}

// Get back to the overworld
bot.test.sayEverywhere('/tp ~ 128 ~')
await onceWithCleanup(bot, 'forcedMove')
await sleep(1000)
bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
await onceWithCleanup(bot, 'spawn')
await sleep(1000)
})

bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
await once(bot, 'spawn')
bot.test.sayEverywhere('/tp 0 128 0')
addTest('nether dimension change event', async (bot) => {
// Test dimension change event
const DimensionChangeTimeout = 10000
bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
// Start listening for dimension change event
const dimensionChange = onceWithCleanup(bot, 'dimensionChange', { timeout: DimensionChangeTimeout })
await onceWithCleanup(bot, 'spawn')

await once(bot, 'forcedMove')
await bot.waitForChunksToLoad()
const [dimensionName] = await dimensionChange
assert.equal(dimensionName, 'the_nether')

// Get back to the overworld
await bot.test.resetNetherRoofToBedrock()
bot.test.sayEverywhere('/tp ~ 128 ~')
await onceWithCleanup(bot, 'forcedMove')
await sleep(1000)
bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
// Check that the dimension change event is fired again
const [dimensionName2] = await onceWithCleanup(bot, 'dimensionChange', { timeout: DimensionChangeTimeout })
assert.equal(dimensionName2, 'overworld')
await sleep(1000)
})

const lowerBlock = bot.blockAt(bot.entity.position.offset(0, -1, 0))
await bot.lookAt(lowerBlock.position, true)
await bot.test.setInventorySlot(36, new Item(signItem.id, 1, 0))
await bot.placeBlock(lowerBlock, new Vec3(0, 1, 0))
return p
return tests
}
9 changes: 9 additions & 0 deletions test/externalTests/plugins/testCommon.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function inject (bot) {
bot.test.fly = fly
bot.test.teleport = teleport
bot.test.resetState = resetState
bot.test.resetNetherRoofToBedrock = resetNetherRoofToBedrock
bot.test.setInventorySlot = setInventorySlot
bot.test.placeBlock = placeBlock
bot.test.runExample = runExample
Expand Down Expand Up @@ -74,6 +75,14 @@ function inject (bot) {
await bot.test.wait(100)
}

async function resetNetherRoofToBedrock () {
bot.chat('/fill ~-5 127 ~-5 ~5 127 ~5 bedrock')
for (let y = 128; y < 131; y++) {
bot.chat(`/fill ~-5 ${y} ~-5 ~5 ${y} ~5 air`)
}
await bot.test.wait(100)
}

async function placeBlock (slot, position) {
bot.setQuickBarSlot(slot - 36)
// always place the block on the top of the block below it, i guess.
Expand Down
2 changes: 1 addition & 1 deletion test/internalTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ for (const supportedVersion of mineflayer.testedVersions) {
assert.ok(bot.world.getColumn(0, 0) === undefined)
done()
})
respawnPacket.worldName = 'minecraft:nether'
respawnPacket.worldName = 'minecraft:the_nether'
if (bot.supportFeature('usesLoginPacket')) {
respawnPacket.dimension.name = 'e'
} else {
Expand Down