fix: bound block-search volume so a large !searchForBlock can't stall the connection - #795
fix: bound block-search volume so a large !searchForBlock can't stall the connection#795atiweb wants to merge 1 commit into
Conversation
bot.findBlocks is synchronous and scans a volume that grows with the cube of maxDistance. With the default count (10000) a search for a rare or absent block never early-exits, so a large radius walks a huge volume on the main thread and blocks the Node event loop long enough for mineflayer to miss keep-alive packets -- the server then drops the bot mid-task. !searchForBlock exposes a radius up to 512 to the model, so this is reachable in normal play. Cap the search radius at 128 (a search beyond the loaded view distance returns nothing useful anyway) and the match count at 4000 in getNearestBlocksWhere, and lower !searchForBlock's max range to 128 to match. A single search can no longer stall the connection.
|
Request to delete this pull request, user has submitted AI slop PRs in the past where they lied about running tests, fixing syntax errors, and testing methods. |
|
I did use AI to help write this, I said so before and I am not hiding it. The #702 case was my fault. I posted a test summary that sounded more solid than what I actually had, and the PR was not ready. That criticism was fair and I took it. This one is 14 lines. It caps maxDistance at 128 and count at 4000 inside getNearestBlocksWhere, and lowers the search_range max in !searchForBlock to match. findBlocks runs on the main thread, so a 512 radius search for a block that is not there blocks the event loop long enough that the server kicks the bot on keepalive. That is what I kept hitting on my own server. I would rather not argue about it here. @MaxRobinsonTheGreat if you want to check it, set search_range to 512 and ask the bot to search for diamond_ore while standing on the surface. On develop the bot drops, with this it does not. If it does not reproduce for you, close it, no problem. |
|
I measured it before saying more. Paper 1.21.11, mineflayer connecting as 1.20.1 through ViaBackwards, 473 columns loaded, 11352 non-empty sections. One searchForBlock style scan for diamond_ore at maxDistance 512 count 10000, time the event loop was blocked: Same scan with this PR at maxDistance 128 count 4000: 1.5 s and 1.7 s, alive both times. So it is not every time, it is the keepalive window. The scan takes 27 to 44 seconds and the server drops the client at 30, so the fastest run survived and the rest did not. I should have said that in my last message instead of saying the bot drops. One thing worth knowing if you read the code: common blocks are fine. stone returns in 40 ms and dirt in 640 ms, because count is reached and it breaks at the layer boundary. It is the rare or absent block that hurts, there is no early exit so it walks the whole octahedron out to apothem 33. diamond_ore and oak_log are both around 30 s. The test is just a bot that connects, waits 25 s for chunks and times one findBlocks call. I can paste it if it helps. |
getNearestBlocksWhere calls bot.findBlocks synchronously, and getNearestBlocks wraps it. The scanned volume grows with the cube of maxDistance, and with the default count of 10000 there is no early exit when the target block is rare or absent, so it walks the whole volume on the main thread.
!searchForBlock lets the model ask for a search_range of up to 512. When it asks for a large radius for something that is not nearby, that scan blocks the event loop long enough that mineflayer misses keepalives and the server drops the bot. From the outside it looks like the bot froze or crashed mid task.
The fix caps maxDistance at 128 and count at 4000 inside getNearestBlocksWhere, and lowers the search_range max in !searchForBlock from 512 to 128 so the model cannot request a radius the engine would only clamp.
findBlocks only returns blocks inside loaded chunks, so past the view distance there is nothing to find and the 128 cap does not drop real results. Capping count downward is strictly less work, since it is an upper bound on matches collected, and 4000 hits within 128 blocks is more than any caller uses.
Two files, +14/-3, no new dependencies.