Skip to content

Commit

Permalink
Add dimensionChange event
Browse files Browse the repository at this point in the history
  • Loading branch information
IceTank committed Jan 4, 2024
1 parent 216cab7 commit 36ddc2f
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 47 deletions.
6 changes: 6 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,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 @@ -110,6 +110,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',
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
130 changes: 88 additions & 42 deletions test/externalTests/nether.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,98 @@
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)
})

const netherPortalLocation = { x: 2, y: 128, z: 0 }

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()
await sleep(1000)
bot.test.sayEverywhere('/setblock ~ ~ ~ nether_portal')
bot.test.sayEverywhere('/setblock ~ ~ ~ portal')
const forcedMoved = onceWithCleanup(bot, 'forcedMove', { timeout: 5000 })
await once(bot, 'spawn')
bot.test.sayEverywhere('/tp 0 128 0')

await forcedMoved
await bot.waitForChunksToLoad()
await sleep(1000)

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))
await bot.placeBlock(lowerBlock, new Vec3(0, 1, 0))

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)
}

bot.test.sayEverywhere(`/tp ${netherPortalLocation.x} ${netherPortalLocation.y} ${netherPortalLocation.z}`)
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('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 once(bot, 'spawn')
bot.test.sayEverywhere('/tp 0 129 0')

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

await once(bot, 'forcedMove')
await bot.waitForChunksToLoad()
await sleep(1000)

bot.test.sayEverywhere(`/tp ${netherPortalLocation.x} ${netherPortalLocation.y} ${netherPortalLocation.z}`)
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
}
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

0 comments on commit 36ddc2f

Please sign in to comment.