-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Various Typing Fixes & Client-Side Render Event (Multiple Client Compatible) #428
base: master
Are you sure you want to change the base?
Changes from 10 commits
26c6373
34073a6
0ec3b58
3d38a3b
40c7f9e
9c6f9ae
d66a470
6ef8107
f9ebe7f
8518325
85105d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
node_modules | ||
package-lock.json | ||
yarn.lock | ||
/test/*.png | ||
versions/ | ||
public/index.js* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"print.colourScheme": "GitHub" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,13 @@ const mineflayer = require('mineflayer') | |
const mineflayerViewer = require('prismarine-viewer').mineflayer | ||
|
||
const bot = mineflayer.createBot({ | ||
username: 'Bot' | ||
username: 'Bot', | ||
host: process.argv[2], | ||
port: isNaN(parseInt(process.argv[3])) ? 25565 : parseInt(process.argv[3]), | ||
version: process.argv[4] ?? '1.16.5' | ||
}) | ||
|
||
bot.once('spawn', () => { | ||
bot.once('spawn', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That doesn't do anything, please undo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
mineflayerViewer(bot, { port: 3000 }) | ||
|
||
const path = [bot.entity.position.clone()] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import * as mineflayer from "mineflayer"; | ||
import { mineflayer as mineflayerLoader } from "prismarine-viewer"; | ||
|
||
import type { Vec3 } from "vec3"; | ||
|
||
const bot = mineflayer.createBot({ | ||
username: "Bot", | ||
}); | ||
|
||
bot.once("spawn", async () => { | ||
mineflayerLoader(bot, { port: 3000 }); | ||
|
||
const path: Vec3[] = [bot.entity.position.clone()]; | ||
if (path[path.length - 1].distanceTo(bot.entity.position) > 1) { | ||
path.push(bot.entity.position.clone()); | ||
bot.viewer.drawLine("path", path); | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,10 +20,28 @@ const viewer = new Viewer(renderer) | |
|
||
let controls = new THREE.OrbitControls(viewer.camera, renderer.domElement) | ||
|
||
const fpsCheck = 1000 // ms | ||
let lastTime = performance.now() | ||
let frameCount = 0 | ||
|
||
function handleUpdate () { | ||
frameCount++ | ||
const currentTime = performance.now() | ||
|
||
if (currentTime - lastTime > fpsCheck) { | ||
const fps = Math.ceil((frameCount / ((currentTime - lastTime) / fpsCheck))) | ||
lastTime = currentTime | ||
frameCount = 0 | ||
if (fps != null) socket.emit('renderFPS', { id: socket.id, fps }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add to doc + use it in an example to explain what it's good for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not know where I would put this server-sided event (renderFPS) firing into docs as there is no mention of server-sided code in the READMEs. I included documentation on the bot.viewer event firing, however. |
||
} | ||
|
||
viewer.update() | ||
} | ||
|
||
function animate () { | ||
window.requestAnimationFrame(animate) | ||
if (controls) controls.update() | ||
viewer.update() | ||
handleUpdate() | ||
renderer.render(viewer.scene, viewer.camera) | ||
} | ||
animate() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,83 @@ module.exports = (bot, { viewDistance = 6, firstPerson = false, port = 3000, pre | |
} | ||
} | ||
|
||
let renderInterval = null | ||
|
||
let maxFPS = 0 | ||
let maxFPSId = null | ||
|
||
const fpsMap = new Map() | ||
|
||
io.on('connection', (socket) => { | ||
const getRenderInterval = (fps) => setInterval(() => bot.viewer.emit('onRender', fps), 1000 / fps) | ||
|
||
const updateListener = ({ id, fps }) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a comment explaining the intent of this; it's far from obvious |
||
if (id == null || fps == null) return | ||
|
||
fpsMap.set(id, fps) | ||
|
||
if (fps > maxFPS) { | ||
maxFPS = fps | ||
if (renderInterval) clearInterval(renderInterval) | ||
|
||
renderInterval = getRenderInterval(maxFPS) | ||
} else if (id === maxFPSId && fps < maxFPS) { | ||
// handle where maxFPSId's fps decreases | ||
|
||
let secondHighest = 0 | ||
let secondHighestId = null | ||
|
||
// check for alternative highest fps | ||
for (const [id1, fps1] of fpsMap) { | ||
if (fps1 > secondHighest && id1 !== id) { | ||
secondHighest = fps1 | ||
secondHighestId = id1 | ||
} | ||
} | ||
|
||
// if there is no alternative highest fps, set maxFPS to current fps | ||
// note: if secondHighest is 0, then there is no alternative highest fps | ||
if (fps > secondHighest) { | ||
maxFPS = fps | ||
maxFPSId = id | ||
if (renderInterval) clearInterval(renderInterval) | ||
|
||
renderInterval = getRenderInterval(maxFPS) | ||
} else { | ||
// if there is an alternative highest fps that is higher than current FPS, | ||
// set maxFPS to the alternative highest fps | ||
maxFPS = secondHighest | ||
maxFPSId = secondHighestId | ||
if (renderInterval) clearInterval(renderInterval) | ||
|
||
renderInterval = getRenderInterval(maxFPS) | ||
} | ||
} | ||
} | ||
|
||
const onSocketRemoval = () => { | ||
if (fpsMap.has(socket.id)) { | ||
fpsMap.delete(socket.id) | ||
} | ||
|
||
if (fpsMap.size === 0) { | ||
maxFPS = 0 | ||
if (renderInterval) clearInterval(renderInterval) | ||
return | ||
} | ||
|
||
for (const [, fps] of fpsMap) { | ||
if (fps > maxFPS) { | ||
maxFPS = fps | ||
} | ||
} | ||
|
||
if (renderInterval) clearInterval(renderInterval) | ||
|
||
renderInterval = getRenderInterval(maxFPS) | ||
} | ||
|
||
socket.on('renderFPS', updateListener) | ||
socket.emit('version', bot.version) | ||
sockets.push(socket) | ||
|
||
|
@@ -75,6 +151,7 @@ module.exports = (bot, { viewDistance = 6, firstPerson = false, port = 3000, pre | |
bot.removeListener('move', botPosition) | ||
worldView.removeListenersFromBot(bot) | ||
sockets.splice(sockets.indexOf(socket), 1) | ||
onSocketRemoval() | ||
}) | ||
}) | ||
|
||
|
@@ -87,5 +164,9 @@ module.exports = (bot, { viewDistance = 6, firstPerson = false, port = 3000, pre | |
for (const socket of sockets) { | ||
socket.disconnect() | ||
} | ||
|
||
// should already always be handled, but hey you never know. | ||
if (renderInterval) clearInterval(renderInterval) | ||
fpsMap.clear() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove