PrismarineJS / mineflayer-collectblock

A simple utility plugin for Mineflayer that add a higher level API for collecting blocks.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues devloping locally. NPM version out of sync with repo

SeanMcCord opened this issue · comments

My goal is to locally develop changes to mineflayer-collectblock. I've found a number of issues while trying to attempt this. This issue is to 1) justify some changes that I think would be beneficial and 2) to seek guidance how how to best address some issues.

Note: I've created example packages to demonstrate the issues.
https://github.com/SeanMcCord/SimpleCollectblockExample
https://github.com/SeanMcCord/collectblock-example

Starting with a simple package that depends on mineflayer, mineflayer-collectblock, and contains the collectblock example, everything works as expected. The bot connects and mines grass. This state is captured here https://github.com/SeanMcCord/SimpleCollectblockExample/tree/d7d9e6d83dc196499479637d759b433ca61e52b8

Let's complicate this by pulling down mineflayer-collectblock and building it. This state is here https://github.com/SeanMcCord/SimpleCollectblockExample/tree/4cbcbcc942923081aac7335a26eea7090b0e9f34 This fails to build as mineflayer-collectblock depends on mineflayer-tool@1.1.0 which depends on mineflayer@^2.32.0 and resolves to mineflayer@2.41.0.

 % yarn why mineflayer
yarn why v1.22.10
[1/4] Why do we have the module "mineflayer"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "mineflayer@2.41.0"
info Has been hoisted to "mineflayer"
info Reasons this module exists
   - "workspace-aggregator-51e79187-6a81-4c11-8e4e-fe524305cc4f" depends on it
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer-tool#mineflayer"
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer-tool#mineflayer-utils#mineflayer"
...
$ ts-standard && tsc && require-self
src/CollectBlock.ts:268:36 - error TS2345: Argument of type 'import("SimpleCollectblockExample/mineflayer-collectblock/node_modules/mineflayer/index").Bot' is not assignable to parameter of type 'import("SimpleCollectblockExample/node_modules/mineflayer/index").Bot'.

268     this.movements = new Movements(bot, mcDataLoader(bot.version))
                                       ~~~

src/index.ts:18:18 - error TS2345: Argument of type '(bot: Bot) => void' is not assignable to parameter of type 'Plugin'.
  Types of parameters 'bot' and 'bot' are incompatible.
    Type 'import("SimpleCollectblockExample/mineflayer-collectblock/node_modules/mineflayer/index").Bot' is not assignable to type 'import("SimpleCollectblockExample/node_modules/mineflayer/index").Bot'.
      The types of 'inventory.findItemRange' are incompatible between these types.
        Type '(start: number, end: number, itemType: number, metadata: number | null, notFull: boolean, nbt: any) => Item | null' is not assignable to type '(start: number, end: number, itemType: number, metadata: number | null, notFull: boolean) => Item | null'.

18   bot.loadPlugin(pathfinderPlugin)
                    ~~~~~~~~~~~~~~~~

Found 2 errors.

Issue 1

It appears that the most recent version of mineflayer-collectblock published to npm is 9c30c96 from Nov 30, 2020. It depends on an old version of mineflayer and the deprecated package mineflayer-utils

 % npm view mineflayer-collectblock dependencies.mineflayer 
^2.32.0
 % npm view mineflayer-collectblock dependencies.mineflayer-pathfinder
^1.0.11
 % npm view mineflayer-collectblock dependencies.mineflayer-utils     
^0.1.3

There are a few approaches that could be taken. 1) We could ignore those build errors and try to run the program. 2) Update mineflayer-tool to use mineflayer@3.6.0, pathfinder@1.6.1, and remove dependency on mineflayer-utils. I've done both and the end result is the same error that I can't resolve.

1) Ignore the errors

State at commit https://github.com/SeanMcCord/SimpleCollectblockExample/tree/281dd314ae6ee6cc0a8ca70611e833cd9e7bca01

yarn workspace collectblock-example start
yarn workspace v1.22.10
yarn run v1.22.10
$ node index.js
undefined:3
[object Object]
        ^^^^^^

SyntaxError: Unexpected identifier
    at EventEmitter.Function (<anonymous>)
    at EventEmitter.emit (events.js:315:20)
    at EventEmitter.monitorMovement (SimpleCollectblockExample/node_modules/mineflayer-pathfinder/index.js:336:17)
    at EventEmitter.emit (events.js:315:20)
    at Timeout.doPhysics [as _onTimeout] (SimpleCollectblockExample/collectblock-example/node_modules/mineflayer/lib/plugins/physics.js:65:13)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)
error Command failed with exit code 1.

I'm not really sure what the issue is here. I would appreciate some guideance.

2) Update depedencies

State after adding mineflayer-tool https://github.com/SeanMcCord/SimpleCollectblockExample/tree/25bdbd235e1cefd840a24fe0136fc7eae3b5c300

mineflayer-tool fails to build in this context

 % yarn workspace mineflayer-tool prepare
yarn workspace v1.22.10
yarn run v1.22.10
$ ts-standard && tsc && require-self
src/Tool.ts:7:1 - error TS2578: Unused '@ts-expect-error' directive.

7 // @ts-expect-error ; nbt has no typescript header
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/Tool.ts:78:55 - error TS2345: Argument of type 'Buffer' is not assignable to parameter of type '{ type: TagType.Byte; value: number; } | { type: TagType.Short; value: number; } | { type: TagType.Int; value: number; } | { type: TagType.Long; value: [number, number]; } | { type: TagType.Float; value: number; } | ... 6 more ... | { ...; }'.
  Type 'Buffer' is missing the following properties from type '{ type: TagType.LongArray; value: [number, number][]; }': type, value

78     const enchants = item?.nbt != null ? nbt.simplify(item.nbt).Enchantments : []
                                                         ~~~~~~~~


Found 2 errors.

To get this up to date we need to:
bump mineflayer from 2.21.0 to 3.6.0
bump mineflayer-pathfinder from 1.0.11 to 1.6.1
remove deprecated package mineflayer-utils 0.1.4
bump prismarine-nbt from 1.3.0 to 1.5.0
bump typescript from 4.0.5 to 4.1.3
Add TaskQueue from https://github.com/PrismarineJS/mineflayer-collectblock/blob/master/src/TaskQueue.ts
Add TemporarySubscriber from https://github.com/PrismarineJS/mineflayer-collectblock/blob/master/src/TemporarySubscriber.ts

Note: We could do this a different way, but this is good enough to demonstrate the issue.

This leaves us in this state https://github.com/SeanMcCord/SimpleCollectblockExample/tree/a34055c9071cbbb8fa94e49ec844b7df7a9985ce

yarn why shows our dependencies are all correct

 % yarn why mineflayer                      
yarn why v1.22.10
[1/4] Why do we have the module "mineflayer"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "mineflayer@3.6.0"
info Reasons this module exists
   - "_project_#collectblock-example" depends on it
   - Hoisted from "_project_#collectblock-example#mineflayer"
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer"
   - Hoisted from "_project_#mineflayer-tool#mineflayer"
...
 % yarn why mineflayer-pathfinder
yarn why v1.22.10
[1/4] Why do we have the module "mineflayer-pathfinder"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "mineflayer-pathfinder@1.6.1"
info Reasons this module exists
   - "_project_#mineflayer-collectblock" depends on it
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer-pathfinder"
   - Hoisted from "_project_#mineflayer-tool#mineflayer-pathfinder"
...
 % yarn why prismarine-nbt
yarn why v1.22.10
[1/4] Why do we have the module "prismarine-nbt"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "prismarine-nbt@1.5.0"
info Reasons this module exists
   - "_project_#mineflayer-tool" depends on it
   - Hoisted from "_project_#mineflayer-tool#prismarine-nbt"
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer-pathfinder#prismarine-nbt"
   - Hoisted from "_project_#collectblock-example#mineflayer#minecraft-protocol#prismarine-nbt"
   - Hoisted from "_project_#mineflayer-collectblock#mineflayer-pathfinder#prismarine-item#prismarine-nbt"
   - Hoisted from "_project_#collectblock-example#mineflayer#prismarine-physics#prismarine-nbt"

We get the same error when mineflayer-tool is prepared

 % yarn workspace mineflayer-tool prepare
yarn workspace v1.22.10
yarn run v1.22.10
$ ts-standard && tsc && require-self
src/Tool.ts:7:1 - error TS2578: Unused '@ts-expect-error' directive.

7 // @ts-expect-error ; nbt has no typescript header
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/Tool.ts:78:55 - error TS2345: Argument of type 'Buffer' is not assignable to parameter of type '{ type: TagType.Byte; value: number; } | { type: TagType.Short; value: number; } | { type: TagType.Int; value: number; } | { type: TagType.Long; value: [number, number]; } | { type: TagType.Float; value: number; } | ... 6 more ... | { ...; }'.
  Type 'Buffer' is missing the following properties from type '{ type: TagType.LongArray; value: [number, number][]; }': type, value

78     const enchants = item?.nbt != null ? nbt.simplify(item.nbt).Enchantments : []
                                                         ~~~~~~~~


Found 2 errors.

I'm not sure what the correct approach is, but given that mineflayer/lib/plugins/digger.js does the same thing. I assume it might be safe to ignore these. Please correct me if this is false.

Removing the unused @ts-expect-error and adding on to line 78 leaves us in this state with a working build. https://github.com/SeanMcCord/SimpleCollectblockExample/tree/5b1c102f92600f14bb3084d00fbe9a2e17097d5b

Now we can fix mineflayer-collectblock by removing an unneeded ts-error. Putting us at this state https://github.com/SeanMcCord/SimpleCollectblockExample/tree/76ed1cda383331617414a0f1e21566525871bdc3

Now for the moment of truth. What we've all been waiting for.

 % yarn workspace collectblock-example start   
yarn workspace v1.22.10
yarn run v1.22.10
$ node index.js
undefined:3
[object Object]
        ^^^^^^

SyntaxError: Unexpected identifier
    at EventEmitter.Function (<anonymous>)
    at EventEmitter.emit (events.js:315:20)
    at EventEmitter.monitorMovement (SimpleCollectblockExample/node_modules/mineflayer-pathfinder/index.js:336:17)
    at EventEmitter.emit (events.js:315:20)
    at Timeout.doPhysics [as _onTimeout] (SimpleCollectblockExample/node_modules/mineflayer/lib/plugins/physics.js:65:13)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

🤔

Issue 2

I haven't been able to figure out why this error is thrown.

One clue is mineflayer/lib/plugins/physics.js line 65. It emits a deprecated event 'physicTick' (singular). By searching for usage we find one in mineflayer-collectblock/src/CollectBlock.ts and another in mineflayer-pathfinder/index.js.

Updating these to 'physicsTick' just changes the error line from 65 to 64, the line physicsTick is emitted.

Looking at the other line from the stacktrace, mineflayer-pathfinder/index.js, we find an emit on 'goal_reached'. https://github.com/PrismarineJS/mineflayer-pathfinder/blob/master/index.js#L337 Adding logging before the emit yields a valid goal object.

 % yarn workspace collectblock-example start
yarn workspace v1.22.10
yarn run v1.22.10
$ node index.js
{ stateGoal: GoalGetToBlock { x: 90, y: 62, z: 178 } }
undefined:3
[object Object]
        ^^^^^^

SyntaxError: Unexpected identifier
    at EventEmitter.Function (<anonymous>)
    at EventEmitter.emit (events.js:315:20)
    at EventEmitter.monitorMovement (/home/sean/Documents/Projects/minecraft_automation/SimpleCollectblockExample/node_modules/mineflayer-pathfinder/index.js:337:17)
    at EventEmitter.emit (events.js:315:20)
    at Timeout.doPhysics [as _onTimeout] (/home/sean/Documents/Projects/minecraft_automation/SimpleCollectblockExample/mineflayer/lib/plugins/physics.js:64:13)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

The only event handlers are as follows

 % grep -R goal_reached . 
./node_modules/mineflayer-pathfinder/index.js:            bot.emit('goal_reached', stateGoal)
./node_modules/mineflayer-pathfinder/index.js:          bot.emit('goal_reached', stateGoal)
./node_modules/mineflayer-pathfinder/examples/test.js:  bot.on('goal_reached', (goal) => {
./node_modules/mineflayer-pathfinder/examples/multiple.js:    bot.on('goal_reached', (goal) => {
./node_modules/mineflayer-pathfinder/readme.md:### goal_reached
./node_modules/mineflayer-pathfinder/history.md:* Fixed `goal_reached` not being called if bot is already at the goal
./node_modules/mineflayer-pathfinder/lib/goto.js:      bot.removeListener('goal_reached', goalReached)
./node_modules/mineflayer-pathfinder/lib/goto.js:    bot.on('goal_reached', goalReached)
./node_modules/mineflayer-collectblock/src/CollectBlock.ts:  tempEvents.subscribeTo('goal_reached', () => {
./node_modules/mineflayer-collectblock/src/Inventory.ts:  events.subscribeTo('goal_reached', () => {
./node_modules/mineflayer-collectblock/lib/CollectBlock.js:    tempEvents.subscribeTo('goal_reached', () => {
./node_modules/mineflayer-collectblock/lib/Inventory.js:    events.subscribeTo('goal_reached', () => {
./node_modules/mineflayer-tool/src/Inventory.ts:  events.subscribeTo('goal_reached', () => {
./node_modules/mineflayer-tool/lib/Inventory.js:    events.subscribeTo('goal_reached', () => {
./mineflayer-collectblock/src/CollectBlock.ts:  tempEvents.subscribeTo('goal_reached', () => {
./mineflayer-collectblock/src/Inventory.ts:  events.subscribeTo('goal_reached', () => {
./mineflayer-collectblock/lib/CollectBlock.js:    tempEvents.subscribeTo('goal_reached', () => {
./mineflayer-collectblock/lib/Inventory.js:    events.subscribeTo('goal_reached', () => {
./mineflayer-tool/src/Inventory.ts:  events.subscribeTo('goal_reached', () => {
./mineflayer-tool/lib/Inventory.js:    events.subscribeTo('goal_reached', () => {

I'll update this issue after testing these.

My current hypothesis is that bot.emit('string', object) fails when an object is provided.

Found the issue.
https://github.com/PrismarineJS/mineflayer-collectblock/blob/master/src/TemporarySubscriber.ts#L22
Second param is 'Function' not callback. The ts-error above it prevented the tools from finding the issue.

My methodology for finding this was to log all the addListener events and console.trace for a specific event type.

 15 function debug_emitter(emitter, name) {
 16     var orig_emit = emitter.emit;
 17     emitter.emit = function() {
 18         let args = [...arguments];
 19         if (args[0] == 'newListener' && args[1] == 'path_update') {
 20           console.trace({args})
 21           console.log({emitter: name, args });
 22         }
 23         orig_emit.apply(emitter, arguments);
 24     }
 25 }
 26 
 27 debug_emitter(bot, 'bot')