voxel / voxel-clientmc

Minecraft client using WebSockets and voxel-engine (voxel.js plugin)
57 stars 13 forks source link

Update for newest wsmc/mineflayer/node-minecraft-protocol 0.16 #16

Closed deathcap closed 8 years ago

deathcap commented 8 years ago

Update voxel-clientmc to work with https://github.com/deathcap/wsmc/pull/21 which now uses node-minecraft-protocol ≥0.16

deathcap commented 8 years ago

First had to update voxel-engine-stackgl 1.1.0 for this critical browser compatibility fix https://github.com/voxel/voxel-shader/issues/11, current status:

mf-worker initializing DedicatedWorkerGlobalScope {__core-js_shared__: Object, undefined: undefined, Infinity: Infinity, Math: Math, NaN: NaN…}
blob:http%3A//localhost%3A9966/121bd57b-2557-49fd-9bbf-77f8714455a5:93784 mf-worker bot Bot {_events: Object, _maxListeners: undefined, _client: Client, username: "user1", isSleeping: false…}
blob:http%3A//localhost%3A9966/121bd57b-2557-49fd-9bbf-77f8714455a5:99087 Uncaught TypeError: Cannot read property 'LOGIN' of undefined
deathcap commented 8 years ago

Chat now works, but no chunks nor movement, server (using GS++) spams:

17:03:39 [INFO] webuser-7 [/127.0.0.1:53196] connected, UUID: 8d2cd1d7-8274-3d0d-a7e6-89b2479b9f88
17:03:39 [INFO] webuser-7 joined the game
17:03:42 [SEVERE] Error in network input
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(1) exceeds writerIndex(0): PooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 0)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
    at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
    at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:243)
    at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
    at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:956)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:514)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
    at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)
    at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)
    at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)
    at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)
    at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)
    at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)
Caused by: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(1) exceeds writerIndex(0): PooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 0)
    at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1138)
    at io.netty.buffer.AbstractByteBuf.readByte(AbstractByteBuf.java:542)
    at com.flowpowered.networking.util.ByteBufUtils.readVarInt(ByteBufUtils.java:79)
    at net.glowstone.net.protocol.GlowProtocol.newReadHeader(GlowProtocol.java:103)
    at net.glowstone.net.pipeline.CodecsHandler.decode(CodecsHandler.java:50)
    at net.glowstone.net.pipeline.CodecsHandler.decode(CodecsHandler.java:19)
    at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89)
    ... 30 more
17:03:42 [SEVERE] Error in network input

Seeing unexpected packet fragmentation from ws in voxel-clientmc (04 length then 00 09 00 00):

websocket received 5 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   75 73 65 72 31                                    user1
WS requested username: user1
websocket received 1 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   04                                                .
forwarding ws -> mc: 0 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
websocket received 4 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   00 09 00 00                                       ....
forwarding ws -> mc: 3 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   09 00 00         

versus mcwebchat example client:

websocket received 14 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   6D 63 77 65 62 63 68 61 74 75 73 65 72 58         mcwebchatuserX

websocket received 4 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   00 09 00 00                                       ....
forwarding ws -> mc: 3 bytes
Offset   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000   09 00 00   

Only wsmc/mineflayer-ws.js was setting options.noPacketFramer = true, but voxel-clientmc uses wsmc/mineflayer-stream.js, since it does not pipe to a websocket-stream directly, but to a duplexer stream so it can pass data to the webworker.

deathcap commented 8 years ago

Chat now works, and am receiving chunk and block update packets, but not seeing any voxels rendered. Receiving the spawn position, it is set currently, and getting some position updates, but sooner or later they stop and the (web) client falls, disconnected from the (mc) server. Need to find out why the chunks aren't displaying.

mf-worker.js receives the chunks, then sends back to the main thread to display (or at least, that's what's supposed to happen).


Debugging further: replacing voxel-clientmc with voxel-land, chunks load ok (so it isn't some other module interfering). The chunk data gets passed to voxel-engine-stackgl this.addChunkToNextUpdate(chunk) successfully, and it contains valid blocks (34 = smooth stone, looks fine). There are meshes briefly added, observed in voxel-shader, but then the meshes quickly drops to zero - and far chunks are removed. The player keeps falling (y dropping). But if I reset the player camera position upwards, game.plugins.get('game-shell-fps-camera').camera.position[1] = -100 (todo: make a simpler better api for changing position), and disable far chunk removal, still see nothing.

deathcap commented 8 years ago

Got sidetracked, trying to untangle voxel-clientmc chunk parsing/generation, updated https://github.com/voxel/voxel-example/ and published a very simple voxel.js terrain generator https://github.com/voxel/voxel-flatland - added it in this module for now, generating chunks to land on while I debug further why the mc chunks are not rendering.

deathcap commented 8 years ago

Another alternative if I can't get this MC to voxel.js chunk translation to work again, is to use https://github.com/rom1504/voxel-prismarine-world - renders a https://github.com/PrismarineJS/prismarine-world using voxel.js (same engine as voxel-clientmc), but if using mineflayer this requires it switching to prismarine-world first https://github.com/PrismarineJS/mineflayer/issues/334

deathcap commented 8 years ago

Looks like the mc chunk is written, as it overwrites the voxel-flatland chunk if I only process (16,0,16):

screen shot 2016-02-06 at 1 59 41 pm
Chunk load (16,0,16)
Created new chunk 0|0|0
Created new chunk 0|1|0
Created new chunk 0|2|0
chunk added in 20.784999999999854
clientmc.js:313 Saving chunk 0|0|0
clientmc.js:313 Saving chunk 0|1|0
clientmc.js:313 Saving chunk 0|2|0
mf-worker spawn position: {"x":30,"y":65,"z":19}

I do see interesting data in game.voxels.chunks (game.voxels.chunks['0|0|0'].data.toString() shows some non-zero voxels), so it isn't clear why it is shown completely as air.

Chunk borders:

screen shot 2016-02-06 at 2 03 53 pm

Chunk load (32,0,16) Created new chunk 1|0|0 Created new chunk 1|1|0 Created new chunk 1|2|0

deathcap commented 8 years ago

The ndarray internal format changed, had to update the ndarray construction on the main thread (reconstituting from the web worker thread). Chunks rendering again:!

screen shot 2016-02-06 at 3 20 48 pm
deathcap commented 8 years ago

Lots of work to go, but should be good enough to merge for now:

screen shot 2016-02-06 at 3 26 27 pm