mineflayer 4.11.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/history.md +3 -0
- package/lib/plugins/physics.js +73 -31
- package/package.json +1 -1
package/docs/history.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## 4.12.0
|
|
2
|
+
* [Mineflayer physics refactor (#2492)](https://github.com/PrismarineJS/mineflayer/commit/d0eb3a1afe6cda7b04ae2f88052cd868ba0c0c4f) (thanks @U5B)
|
|
3
|
+
|
|
1
4
|
## 4.11.0
|
|
2
5
|
* [Import changedSlots computation from prismarine-windows (#3134)](https://github.com/PrismarineJS/mineflayer/commit/e5b5eeecf1133c1c80c0ef48d6e72fed77d84834) (thanks @kaduvert)
|
|
3
6
|
* [Make the place block success check ignore block updates received with no block type changes (#3090)](https://github.com/PrismarineJS/mineflayer/commit/bbdd93afe2e31d1f1e899176e7edf8e73af5d5d3) (thanks @PondWader)
|
package/lib/plugins/physics.js
CHANGED
|
@@ -12,9 +12,10 @@ module.exports = inject
|
|
|
12
12
|
const PI = Math.PI
|
|
13
13
|
const PI_2 = Math.PI * 2
|
|
14
14
|
const PHYSICS_INTERVAL_MS = 50
|
|
15
|
-
const PHYSICS_TIMESTEP = PHYSICS_INTERVAL_MS / 1000
|
|
15
|
+
const PHYSICS_TIMESTEP = PHYSICS_INTERVAL_MS / 1000 // 0.05
|
|
16
16
|
|
|
17
|
-
function inject (bot, { physicsEnabled }) {
|
|
17
|
+
function inject (bot, { physicsEnabled, maxCatchupTicks }) {
|
|
18
|
+
const PHYSICS_CATCHUP_TICKS = maxCatchupTicks ?? 4
|
|
18
19
|
const world = { getBlock: (pos) => { return bot.blockAt(pos, false) } }
|
|
19
20
|
const physics = Physics(bot.registry, world)
|
|
20
21
|
|
|
@@ -38,6 +39,7 @@ function inject (bot, { physicsEnabled }) {
|
|
|
38
39
|
let lastPhysicsFrameTime = null
|
|
39
40
|
let shouldUsePhysics = false
|
|
40
41
|
bot.physicsEnabled = physicsEnabled ?? true
|
|
42
|
+
let deadTicks = 21
|
|
41
43
|
|
|
42
44
|
const lastSent = {
|
|
43
45
|
x: 0,
|
|
@@ -51,25 +53,44 @@ function inject (bot, { physicsEnabled }) {
|
|
|
51
53
|
|
|
52
54
|
// This function should be executed each tick (every 0.05 seconds)
|
|
53
55
|
// How it works: https://gafferongames.com/post/fix_your_timestep/
|
|
56
|
+
|
|
57
|
+
// WARNING: THIS IS NOT ACCURATE ON WINDOWS (15.6 Timer Resolution)
|
|
58
|
+
// use WSL or switch to Linux
|
|
59
|
+
// see: https://discord.com/channels/413438066984747026/519952494768685086/901948718255833158
|
|
54
60
|
let timeAccumulator = 0
|
|
61
|
+
let catchupTicks = 0
|
|
55
62
|
function doPhysics () {
|
|
56
63
|
const now = performance.now()
|
|
57
64
|
const deltaSeconds = (now - lastPhysicsFrameTime) / 1000
|
|
58
65
|
lastPhysicsFrameTime = now
|
|
59
66
|
|
|
60
67
|
timeAccumulator += deltaSeconds
|
|
61
|
-
|
|
68
|
+
catchupTicks = 0
|
|
62
69
|
while (timeAccumulator >= PHYSICS_TIMESTEP) {
|
|
63
|
-
|
|
64
|
-
physics.simulatePlayer(new PlayerState(bot, controlState), world).apply(bot)
|
|
65
|
-
bot.emit('physicsTick')
|
|
66
|
-
bot.emit('physicTick') // Deprecated, only exists to support old plugins. May be removed in the future
|
|
67
|
-
}
|
|
68
|
-
updatePosition(PHYSICS_TIMESTEP)
|
|
70
|
+
tickPhysics(now)
|
|
69
71
|
timeAccumulator -= PHYSICS_TIMESTEP
|
|
72
|
+
catchupTicks++
|
|
73
|
+
if (catchupTicks >= PHYSICS_CATCHUP_TICKS) break
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function tickPhysics (now) {
|
|
78
|
+
if (bot.blockAt(bot.entity.position) == null) return // check if chunk is unloaded
|
|
79
|
+
if (bot.physicsEnabled && shouldUsePhysics) {
|
|
80
|
+
physics.simulatePlayer(new PlayerState(bot, controlState), world).apply(bot)
|
|
81
|
+
bot.emit('physicsTick')
|
|
82
|
+
bot.emit('physicTick') // Deprecated, only exists to support old plugins. May be removed in the future
|
|
83
|
+
}
|
|
84
|
+
if (shouldUsePhysics) {
|
|
85
|
+
updatePosition(now)
|
|
70
86
|
}
|
|
71
87
|
}
|
|
72
88
|
|
|
89
|
+
// remove this when 'physicTick' is removed
|
|
90
|
+
bot.on('newListener', (name) => {
|
|
91
|
+
if (name === 'physicTick') console.warn('Mineflayer detected that you are using a deprecated event (physicTick)! Please use this event (physicsTick) instead.')
|
|
92
|
+
})
|
|
93
|
+
|
|
73
94
|
function cleanup () {
|
|
74
95
|
clearInterval(doPhysicsTimer)
|
|
75
96
|
doPhysicsTimer = null
|
|
@@ -117,17 +138,25 @@ function inject (bot, { physicsEnabled }) {
|
|
|
117
138
|
return dYaw
|
|
118
139
|
}
|
|
119
140
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (
|
|
141
|
+
// returns false if packet should be sent, true if not
|
|
142
|
+
function sendPositionPacketInDeath () {
|
|
143
|
+
if (bot.isAlive === true) deadTicks = 0
|
|
144
|
+
if (bot.isAlive === false && deadTicks <= 20) deadTicks++
|
|
145
|
+
if (deadTicks >= 20) return true
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function updatePosition (now) {
|
|
150
|
+
// Only send updates for 20 ticks after death
|
|
151
|
+
if (sendPositionPacketInDeath()) return
|
|
123
152
|
|
|
124
153
|
// Increment the yaw in baby steps so that notchian clients (not the server) can keep up.
|
|
125
154
|
const dYaw = deltaYaw(bot.entity.yaw, lastSentYaw)
|
|
126
155
|
const dPitch = bot.entity.pitch - (lastSentPitch || 0)
|
|
127
156
|
|
|
128
157
|
// Vanilla doesn't clamp yaw, so we don't want to do it either
|
|
129
|
-
const maxDeltaYaw =
|
|
130
|
-
const maxDeltaPitch =
|
|
158
|
+
const maxDeltaYaw = PHYSICS_TIMESTEP * physics.yawSpeed
|
|
159
|
+
const maxDeltaPitch = PHYSICS_TIMESTEP * physics.pitchSpeed
|
|
131
160
|
lastSentYaw += math.clamp(-maxDeltaYaw, dYaw, maxDeltaYaw)
|
|
132
161
|
lastSentPitch += math.clamp(-maxDeltaPitch, dPitch, maxDeltaPitch)
|
|
133
162
|
|
|
@@ -137,24 +166,28 @@ function inject (bot, { physicsEnabled }) {
|
|
|
137
166
|
const onGround = bot.entity.onGround
|
|
138
167
|
|
|
139
168
|
// Only send a position update if necessary, select the appropriate packet
|
|
140
|
-
const positionUpdated = lastSent.x !== position.x || lastSent.y !== position.y || lastSent.z !== position.z
|
|
169
|
+
const positionUpdated = lastSent.x !== position.x || lastSent.y !== position.y || lastSent.z !== position.z ||
|
|
170
|
+
// Send a position update every second, even if no other update was made
|
|
171
|
+
// This function rounds to the nearest 50ms (or PHYSICS_INTERVAL_MS) and checks if a second has passed.
|
|
172
|
+
(Math.round((now - lastSent.time) / PHYSICS_INTERVAL_MS) * PHYSICS_INTERVAL_MS) >= 1000
|
|
141
173
|
const lookUpdated = lastSent.yaw !== yaw || lastSent.pitch !== pitch
|
|
142
174
|
|
|
143
|
-
if (positionUpdated && lookUpdated
|
|
175
|
+
if (positionUpdated && lookUpdated) {
|
|
144
176
|
sendPacketPositionAndLook(position, yaw, pitch, onGround)
|
|
145
|
-
|
|
177
|
+
lastSent.time = now // only reset if positionUpdated is true
|
|
178
|
+
} else if (positionUpdated) {
|
|
146
179
|
sendPacketPosition(position, onGround)
|
|
147
|
-
|
|
180
|
+
lastSent.time = now // only reset if positionUpdated is true
|
|
181
|
+
} else if (lookUpdated) {
|
|
148
182
|
sendPacketLook(yaw, pitch, onGround)
|
|
149
|
-
} else if (
|
|
150
|
-
// Send a position packet every second, even if no update was made
|
|
151
|
-
sendPacketPosition(position, onGround)
|
|
152
|
-
lastSent.time = performance.now()
|
|
153
|
-
} else if (positionUpdateSentEveryTick && bot.isAlive) {
|
|
183
|
+
} else if (positionUpdateSentEveryTick || onGround !== lastSent.onGround) {
|
|
154
184
|
// For versions < 1.12, one player packet should be sent every tick
|
|
155
185
|
// for the server to update health correctly
|
|
186
|
+
// For versions >= 1.12, onGround !== lastSent.onGround should be used, but it doesn't ever trigger outside of login
|
|
156
187
|
bot._client.write('flying', { onGround: bot.entity.onGround })
|
|
157
188
|
}
|
|
189
|
+
|
|
190
|
+
lastSent.onGround = bot.entity.onGround // onGround is always set
|
|
158
191
|
}
|
|
159
192
|
|
|
160
193
|
bot.physics = physics
|
|
@@ -262,7 +295,14 @@ function inject (bot, { physicsEnabled }) {
|
|
|
262
295
|
// player position and look (clientbound)
|
|
263
296
|
bot._client.on('position', (packet) => {
|
|
264
297
|
bot.entity.height = 1.62
|
|
265
|
-
|
|
298
|
+
|
|
299
|
+
// Velocity is only set to 0 if the flag is not set, otherwise keep current velocity
|
|
300
|
+
const vel = bot.entity.velocity
|
|
301
|
+
vel.set(
|
|
302
|
+
packet.flags & 1 ? vel.x : 0,
|
|
303
|
+
packet.flags & 2 ? vel.y : 0,
|
|
304
|
+
packet.flags & 4 ? vel.z : 0
|
|
305
|
+
)
|
|
266
306
|
|
|
267
307
|
// If flag is set, then the corresponding value is relative, else it is absolute
|
|
268
308
|
const pos = bot.entity.position
|
|
@@ -280,19 +320,14 @@ function inject (bot, { physicsEnabled }) {
|
|
|
280
320
|
|
|
281
321
|
if (bot.supportFeature('teleportUsesOwnPacket')) {
|
|
282
322
|
bot._client.write('teleport_confirm', { teleportId: packet.teleportId })
|
|
283
|
-
// Force send an extra packet to be like vanilla client
|
|
284
|
-
sendPacketPositionAndLook(pos, newYaw, newPitch, bot.entity.onGround)
|
|
285
323
|
}
|
|
286
324
|
sendPacketPositionAndLook(pos, newYaw, newPitch, bot.entity.onGround)
|
|
287
325
|
|
|
288
326
|
shouldUsePhysics = true
|
|
289
|
-
bot.
|
|
327
|
+
bot.jumpTicks = 0
|
|
290
328
|
lastSentYaw = bot.entity.yaw
|
|
329
|
+
lastSentPitch = bot.entity.pitch
|
|
291
330
|
|
|
292
|
-
if (doPhysicsTimer === null) {
|
|
293
|
-
lastPhysicsFrameTime = performance.now()
|
|
294
|
-
doPhysicsTimer = setInterval(doPhysics, PHYSICS_INTERVAL_MS)
|
|
295
|
-
}
|
|
296
331
|
bot.emit('forcedMove')
|
|
297
332
|
})
|
|
298
333
|
|
|
@@ -313,5 +348,12 @@ function inject (bot, { physicsEnabled }) {
|
|
|
313
348
|
|
|
314
349
|
bot.on('mount', () => { shouldUsePhysics = false })
|
|
315
350
|
bot.on('respawn', () => { shouldUsePhysics = false })
|
|
351
|
+
bot.on('login', () => {
|
|
352
|
+
shouldUsePhysics = false
|
|
353
|
+
if (doPhysicsTimer === null) {
|
|
354
|
+
lastPhysicsFrameTime = performance.now()
|
|
355
|
+
doPhysicsTimer = setInterval(doPhysics, PHYSICS_INTERVAL_MS)
|
|
356
|
+
}
|
|
357
|
+
})
|
|
316
358
|
bot.on('end', cleanup)
|
|
317
359
|
}
|