extremeheat / JSPyBridge

🌉. Bridge to interoperate Node.js and Python
MIT License
690 stars 53 forks source link

Chain call crash in Python-JavaScript bridge when accessing object properties. #144

Open seniorprogphp opened 1 month ago

seniorprogphp commented 1 month ago

Context: The bug occurs when using the Python-JavaScript bridge and the mineflayer module. Replay conditions: The crash occurs when methods are called in a chain, e.g. playerEntity.position.offset(...).

from javascript import require, On
mineflayer = require('mineflayer')

bot = mineflayer.createBot({
  'host': 'localhost',
  'port': 30034,
  'username': 'lookAt_Bot'
})

def lookAtNearestPlayer():
    playerEntity = bot.nearestEntity()

    if not playerEntity: 
        return

    pos = playerEntity.position.offset(0, playerEntity.height, 0)
    bot.lookAt(pos)

@On(bot, 'chat')
def chathandle(this, username, message, *args):
    if username == "sffkjsdfsfd" and message == "asdkasdjkadjskajsdj":
        bot.chat('asjdkjasdkasjd')

@On(bot, 'physicsTick')
def handle(*args):
    lookAtNearestPlayer()

Workaround: Assigning an intermediate value to a variable before calling a method prevents a crash.

pos = playerEntity.position
pos = pos.offset(0, playerEntity.height, 0)
bot.lookAt(pos)
seniorprogphp commented 1 month ago

JS analog

const mineflayer = require('mineflayer')

const bot = mineflayer.createBot({
  host: 'localhost',
  port: 37269,
  username: 'lookAt_Bot'
})

function lookAtNearestPlayer () {
  const playerFilter = (entity) => entity.type === 'player'
  const playerEntity = bot.nearestEntity(playerFilter)

  if (!playerEntity) return

  const pos = playerEntity.position.offset(0, playerEntity.height, 0)
  bot.lookAt(pos)
}

bot.on('physicTick', lookAtNearestPlayer)
seniorprogphp commented 1 month ago

the screenshot and log are old, but the error is the same.

Error: https://imgur.com/Ww9h3ci https://github.com/PrismarineJS/mineflayer/issues/2996#issue-1642661073

C:\Users\root\Desktop>python main.py [JSE] node:internal/process/promises:288 [JSE]             triggerUncaughtException(err, true /* fromPromise */); [JSE]             ^ [JSE] [JSE] [🐍  Python Error  JavaScript attempt to call 'some function' in Python failed: [JSE] > bot.emit('physicsTick') [JSE]   at Timeout.doPhysics [as _onTimeout] (C:\Users\root\AppData\Local\Programs\Python\Python39\lib\site-packages\javascript\js\node_modules\mineflayer\lib\plugins\physics.js:65:13) [JSE]   at listOnTimeout (node:internal/timers:569:17) [JSE]   at process.processTimers (node:internal/timers:512:7) [JSE] [JSE] ... across the bridge ... [JSE] [JSE] > lookAtNearestPlayer() [JSE]   at handle (C:\Users\root\Desktop\main.py:26) [JSE] > pos = playerEntity.position.offset(0, playerEntity.height, 0) [JSE]   at lookAtNearestPlayer (C:\Users\root\Desktop\main.py:16) [JSE] 🌉 javascript.errors.JavaScriptError: ('offset', "TypeError: Cannot read properties of undefined (reading 'offset')\n    at Bridge.call (C:\\Users\\root\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\javascript\\js\\bridge.js:136:35)\n    at Bridge.onMessage (C:\\Users\\root\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\javascript\\js\\bridge.js:226:25)\n    at Socket.<anonymous> (C:\\Users\\root\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\javascript\\js\\bridge.js:278:18)\n    at Socket.emit (node:events:513:28)\n    at addChunk (node:internal/streams/readable:324:12)\n    at readableAddChunk (node:internal/streams/readable:297:9)\n    at Readable.push (node:internal/streams/readable:234:10)\n    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)")] [JSE] [JSE] Node.js v18.15.0
seniorprogphp commented 1 month ago

@extremeheat