Skip to content
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

Chunks aren't appearing on the client #5

Open
robotman3000 opened this issue Jan 19, 2017 · 57 comments
Open

Chunks aren't appearing on the client #5

robotman3000 opened this issue Jan 19, 2017 · 57 comments

Comments

@robotman3000
Copy link
Owner

No idea with this one. MiNet documentation suggests something to look into

@robotman3000 robotman3000 added this to the Basic Proxy milestone Jan 19, 2017
@MrPowerGamerBR
Copy link

When I was creating my own proxy, I used this class to translate the chunk data

https://gist.github.com/MrPowerGamerBR/e751de1a5cf17fa93212768e91648f64

However this is very old, probably from 0.14/0.15, but maybe it will be useful.

What is the worst part is the "PEChunkRadiusUpdatePacket" (or it was another packet?), if you don't sent it, the client won't render the chunks for some reason.

@robotman3000
Copy link
Owner Author

Can you tell me everything you know about getting the Minecraft PE client to render chunks?
Also I have noticed that the client doesn't seem to ever send movement packets. Do you have any idea why?

@MrPowerGamerBR
Copy link

@robotman3000 if I knew why the chunks aren't rendered, I would already fixed it 😋

What you can do is creating a plugin for Nukkit to see what packets are sent/received by the client/server.

Also, try sending a full stone chunk, then you can find out if it is the chunk translator issue, of if it is the client that doesn't want to render the chunk.

Also, maybe they aren't sent because the client didn't receive any chunk data, so the client doesn't send any movement packets.

@MrPowerGamerBR
Copy link

I tried debugging the chunk packets and I didn't find anything useful...

I removed every PC chunk translator packet and changed the initial air chunks to stone and sent the request chunk packet to the client... nothing, still air.

Try figuring out how to send a full stone chunk before trying to figure out the PC chunk translator, because, if you figure out how to send successfully a stone chunk, then you know 100% that it is the translator that is wrong.

@MrPowerGamerBR
Copy link

@robotman3000 after looking a little bit here https://confluence.yawk.at/display/PEPROTOCOL/Login+sequence I found something wrong with DragonProxy

The client first requests the chunk, then you send the chunk data and then you send the updated chunk packet.

But in DragonProxy it is sending the chunk data, then the client requests the chunk and then you send the updated chunk packet.

I don't know if the order matters, but hey, maybe that's the issue, right?

@MrPowerGamerBR
Copy link

This is the packet order in Nukkit

https://gist.github.com/MrPowerGamerBR/aac5d16b62ffedd80f429bac2d10d752

So ignore what I said, the chunk request/chunk data/update packet order doesn't matter

@MrPowerGamerBR
Copy link

This is the packet order in Nukkit

https://gist.github.com/MrPowerGamerBR/aac5d16b62ffedd80f429bac2d10d752

So ignore what I said, the chunk request/chunk data/update packet order doesn't matter

And, if you need, here is a dump of a (working) FullChunkDataPacket in text format: https://gist.github.com/MrPowerGamerBR/b29670c92949a297b716e269d2b488b0

@robotman3000
Copy link
Owner Author

What you can do is send that FullChunkDataPacket dump for every chunk you send to the client. That way you can test the translator and packet order logic independent of the actual chunk translation.
@NiclasOlofsson might be able to help us solve this problem.

@robotman3000
Copy link
Owner Author

I have, actually made a plugin like you suggested already.

Here is the source and plugin jar for you to use
Packet Plugin.zip
Packet Capture Jar.zip

Packet Serialization is somewhat broken because some of the nukkit packets have circular references that mess up GSon

@MrPowerGamerBR
Copy link

MrPowerGamerBR commented Jan 21, 2017 via email

@MrPowerGamerBR
Copy link

@robotman3000 here is my plugin, it doesn't have the StackOverflow issue due to circular references.

https://gist.github.com/MrPowerGamerBR/0ed5b4f6b6d1dd0f04ba641934bbbf82

https://gist.github.com/MrPowerGamerBR/c3580d57f71ea50ce751224db7486cc7

@MrPowerGamerBR
Copy link

Done more debugging and I still couldn't find the issue, I created a command to send the chunks when I want but still, nothing is rendered.

@NiclasOlofsson
Copy link

I haven't checked your code. But I trust you understand that the chunk-format completely changed with 1.0.

@robotman3000
Copy link
Owner Author

I had begun to understand that. @NiclasOlofsson Do you have good documentation on this new chunk-format?

@robotman3000
Copy link
Owner Author

Also, will the client render the chunks once it receives them or are there other packets that have to be sent first?

@MrPowerGamerBR
Copy link

@robotman3000 if you are using the Nukkit classes, then I suppose that they are correct when you use toFastBinary, yeah, the translator is probably wrong, but the flat chunk method shouldn't be wrong.

Well, if it is wrong, then Nukkit is also wrong, but Nukkit works, so...

@NiclasOlofsson
Copy link

if it spawns, then it's usually just the chunks that are missing.

@robotman3000
Copy link
Owner Author

So, that would mean that the problem is that the proxy isn't sending properly formatted chunks to the client. I am able to get the client to spawn, but it won't send movement packets and it won't render any chunks. I can get it to send packets when the clients inventory is opened, though.

@robotman3000
Copy link
Owner Author

Actually, when I use toBinary (I think that's it) the client crashes. toFastBinary doesn't appear to have any effect

@MrPowerGamerBR
Copy link

@NiclasOlofsson this is what happens when you try to login

http://i.imgur.com/c6Uqet4.png

DragonProxy sends a flat chunk with only air on login and then the PC server chunks after the player is logged in, the PC chunk translator is probably broken since 0.14, so I disabled it for testing, however the flat chunk with only air should work since it is from Nukkit, and Nukkit works in 1.0.0

@MrPowerGamerBR
Copy link

@robotman3000 also, don't forget to change the world format in the flat chunk method, it should be Anvil, not MCRegion. (due to the 256 world height limit, MCRegion only supports up to 128)

@MrPowerGamerBR
Copy link

@robotman3000 To be honest, I don't even know if the toBinary/toFastBinary are even used in Nukkit when sending packets, after taking a quick look at the source code it seems that method is never used when sending chunk data.

@MrPowerGamerBR
Copy link

@robotman3000 yeah, toBinary/toFastBinary shouldn't be used at all, AFAIK they are used to save chunk data to disk, not to transform the data for packets.

@robotman3000
Copy link
Owner Author

Well there's my problem.

@MrPowerGamerBR
Copy link

@robotman3000 here is how Nukkit does it magic for chunk data

    @Override
    public void onRun() {
        Chunk chunk = Chunk.fromFastBinary(this.chunk);
        byte[] ids = chunk.getBlockIdArray();
        byte[] meta = chunk.getBlockDataArray();
        byte[] blockLight = chunk.getBlockLightArray();
        byte[] skyLight = chunk.getBlockSkyLightArray();
        int[] heightMap = chunk.getHeightMapArray();
        int[] biomeColors = chunk.getBiomeColorArray();
        ByteBuffer buffer = ByteBuffer.allocate(
                16 * 16 * (128 + 64 + 64 + 64)
                        + 256
                        + 256
                        + this.blockEntities.length
        );

        ByteBuffer orderedIds = ByteBuffer.allocate(16 * 16 * 128);
        ByteBuffer orderedData = ByteBuffer.allocate(16 * 16 * 64);
        ByteBuffer orderedSkyLight = ByteBuffer.allocate(16 * 16 * 64);
        ByteBuffer orderedLight = ByteBuffer.allocate(16 * 16 * 64);

        for (int x = 0; x < 16; ++x) {
            for (int z = 0; z < 16; ++z) {
                orderedIds.put(this.getColumn(ids, x, z));
                orderedData.put(this.getHalfColumn(meta, x, z));
                orderedSkyLight.put(this.getHalfColumn(skyLight, x, z));
                orderedLight.put(this.getHalfColumn(blockLight, x, z));
            }
        }

        ByteBuffer orderedHeightMap = ByteBuffer.allocate(heightMap.length);
        for (int i : heightMap) {
            orderedHeightMap.put((byte) (i & 0xff));
        }
        ByteBuffer orderedBiomeColors = ByteBuffer.allocate(biomeColors.length * 4);
        for (int i : biomeColors) {
            orderedBiomeColors.put(Binary.writeInt(i));
        }

        this.setResult(
                buffer
                        .put(orderedIds)
                        .put(orderedData)
                        .put(orderedSkyLight)
                        .put(orderedLight)
                        .put(orderedHeightMap)
                        .put(orderedBiomeColors)
                        .put(this.blockEntities)
                        .array()
        );
}

@robotman3000
Copy link
Owner Author

Where was that?

@MrPowerGamerBR
Copy link

Strange, Nukkit uses that code to encode the chunks and it works (at least in the Anvil map format, not sure about LevelDB/MCRegion)

Or probably that is old code that for some reason is still in Nukkit

@NiclasOlofsson
Copy link

NiclasOlofsson commented Jan 21, 2017

@MrPowerGamerBR
Copy link

Here is how Nukkit handles chunk data in MCRegion

    @Override
    public AsyncTask requestChunkTask(int x, int z) throws ChunkException {
        BaseFullChunk chunk = this.getChunk(x, z, false);
        if (chunk == null) {
            throw new ChunkException("Invalid Chunk Sent");
        }

        byte[] tiles = new byte[0];

        if (!chunk.getBlockEntities().isEmpty()) {
            List<CompoundTag> tagList = new ArrayList<>();

            for (BlockEntity blockEntity : chunk.getBlockEntities().values()) {
                if (blockEntity instanceof BlockEntitySpawnable) {
                    tagList.add(((BlockEntitySpawnable) blockEntity).getSpawnCompound());
                }
            }

            try {
                tiles = NBTIO.write(tagList, ByteOrder.LITTLE_ENDIAN, true);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        Map<Integer, Integer> extra = chunk.getBlockExtraDataArray();
        BinaryStream extraData;
        if (!extra.isEmpty()) {
            extraData = new BinaryStream();
            extraData.putLInt(extra.size());
            for (Map.Entry<Integer, Integer> entry : extra.entrySet()) {
                extraData.putLInt(entry.getKey());
                extraData.putLShort(entry.getValue());
            }
        } else {
            extraData = null;
        }

        BinaryStream stream = new BinaryStream();
        stream.put(chunk.getBlockIdArray());
        stream.put(chunk.getBlockDataArray());
        stream.put(chunk.getBlockSkyLightArray());
        stream.put(chunk.getBlockLightArray());
        for (int height : chunk.getHeightMapArray()) {
            stream.putByte((byte) height);
        }
        for (int color : chunk.getBiomeColorArray()) {
            stream.put(Binary.writeInt(color));
        }
        if (extraData != null) {
            stream.put(extraData.getBuffer());
        } else {
            stream.putLInt(0);
        }
        stream.put(tiles);

        this.getLevel().chunkRequestCallback(x, z, stream.getBuffer());

        return null;
}

I also don't know if it is right, but Nukkit uses that

@NiclasOlofsson
Copy link

that's also wrong

@robotman3000
Copy link
Owner Author

Then... how is Nukkit still working????

@robotman3000
Copy link
Owner Author

@MrPowerGamerBR
Copy link

@robotman3000 I'm probably looking at the wrong place then... I even tried looking at the 1.0.0 branch (I think master is already on 1.0.0 but just to be sure) but the code is the same

@NiclasOlofsson
Copy link

This one is "correct". At least from just looking at it.

https://github.com/Nukkit/Nukkit/blob/master/src/main/java/cn/nukkit/level/format/anvil/Anvil.java#L98

@NiclasOlofsson
Copy link

Regarding that wiki @robotman3000: It's still valid, but it's not the problem you have.

@robotman3000
Copy link
Owner Author

So, @MrPowerGamerBR in UpstreamSession you can try changing
cn.nukkit.level.format.mcregion.Chunk chunk = cn.nukkit.level.format.mcregion.Chunk.getEmptyChunk(chunkX, chunkZ);

to

cn.nukkit.level.format.anvil.Chunk chunk = cn.nukkit.level.format.anvil.Chunk.getEmptyChunk(chunkX, chunkZ);

in the getFlatChunk method and see if it works.

@robotman3000
Copy link
Owner Author

@NiclasOlofsson when does that problem apply?

@NiclasOlofsson
Copy link

It applies when you send chunks, and the last chunk is not air. You never see that in a regular world, because it keeps generate chunks .. but for a PVP server, loading a limited map, it always apply. You can recognize the problem easily since you can't see the blocks, but you can interact with them.

The problem you are having is a problem we all had before sending proper chunks. It spawns without chunks. Earlier versions wouldn't even spawn, so that changed with 1.0.

@MrPowerGamerBR
Copy link

	private DataPacket getFlatChunkPacket(int chunkX, int chunkZ, int blockId) {
		FullChunkDataPacket pePacket = new FullChunkDataPacket();

		cn.nukkit.level.format.anvil.Chunk chunk = cn.nukkit.level.format.anvil.Chunk.getEmptyChunk(chunkX, chunkZ);

		{
			int x = 0;
			int y = 0;
			int z = 0;
			while (z > 16) {
				while (x > 16) {
					while (y > 256) {
						chunk.setBlockId(x, y, z, 1);
						y++;
					}
					x++;
				}
				z++;
			}
		}
		pePacket.chunkX = chunkX;
		pePacket.chunkZ = chunkZ;

		byte[] blockEntities = new byte[0];

		if (!chunk.getBlockEntities().isEmpty()) {
			List<CompoundTag> tagList = new ArrayList<>();

			for (BlockEntity blockEntity : chunk.getBlockEntities().values()) {
				if (blockEntity instanceof BlockEntitySpawnable) {
					tagList.add(((BlockEntitySpawnable) blockEntity).getSpawnCompound());
				}
			}

			try {
				blockEntities = NBTIO.write(tagList, ByteOrder.LITTLE_ENDIAN, true);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

		Map<Integer, Integer> extra = chunk.getBlockExtraDataArray();
		BinaryStream extraData;
		if (!extra.isEmpty()) {
			extraData = new BinaryStream();
			extraData.putVarInt(extra.size());
			for (Map.Entry<Integer, Integer> entry : extra.entrySet()) {
				extraData.putVarInt(entry.getKey());
				extraData.putLShort(entry.getValue());
			}
		} else {
			extraData = null;
		}

		BinaryStream stream = new BinaryStream();
		stream.putByte((byte) 16); // Send all chunk sections
		for (cn.nukkit.level.format.ChunkSection section : chunk.getSections()) {
			stream.putByte((byte) 0);
			stream.put(section.getBytes());
		}
		for (int height : chunk.getHeightMapArray()) {
			stream.putByte((byte) height);
		}
		stream.put(new byte[256]);
		stream.put(chunk.getBiomeIdArray());
		stream.putByte((byte) 0);
		if (extraData != null) {
			stream.put(extraData.getBuffer());
		} else {
			stream.putVarInt(0);
		}
		stream.put(blockEntities);

		pePacket.data = stream.getBuffer();
		return pePacket;
	}

This doesn't work, will probably take a look later, anyway, thanks for helping @NiclasOlofsson 👍 (I would use MiNET if it worked on Linux, maybe someday when Mono implements crypto...)

@MrPowerGamerBR
Copy link

The problem is that I can't even figure out what the client even thinks about the packet, in Minecraft PC when you send a invalid packet it crashes and says in the crash log what was the issue, but in MCPE/MCW10 it seems it just throws away the packet like nothing never happened.

@NiclasOlofsson
Copy link

Nukkit is just fine, so I'd stick to that if I wanted to do anything but Windows :-) The more servers, the merrier !

@MrPowerGamerBR
Copy link

@NiclasOlofsson if Nukkit was still actively maintained... nowadays it only receives minimal bug fixes and protocol updates 😢. Even a lot of bugs that doesn't exist anymore in PocketMine-MP still exists in Nukkit

@NiclasOlofsson
Copy link

Oh, i thought nukkit had payed developers. But maybe I'm mistaking that with some other server.

@robotman3000
Copy link
Owner Author

Yes @NiclasOlofsson, thanks for your help 👍 . @MrPowerGamerBR I share your frustration with the lack of logging

@MrPowerGamerBR
Copy link

MrPowerGamerBR commented Jan 21, 2017

@NiclasOlofsson you are probably mistaking with Voxelwind, Voxelwind is sponsored by The Hive, however Voxelwind is on hold because the maintainer is busy with other projects. (And Voxelwind is nowhere near completion, the only thing you can do yet is join the server, place and break some blocks on a flat terrain, that's it.... but it has future)

Nukkit is literally a PocketMine-MP port to Java

@NiclasOlofsson
Copy link

Yeah, you are right.

No project that doesn't get actively maintained at that stage has a "future". Not really.

@MrPowerGamerBR
Copy link

@NiclasOlofsson well, Tux (minecrafter) said why he has Voxelwind on hold (he got busy with real life + other Minecraft related project) so that's why it isn't actively maintained.

So maybe I should change to "it had a future and maybe it has a future if it gets actively maintained again"

@MrPowerGamerBR
Copy link

Four hours later and I still couldn't figure out how to handle those chunks. Will keep trying...

It doesn't help that you don't receive any feedback from MCPE, because only three things can happen when dealing with packets:

  1. Nothing happens and you can't figure out why
  2. The client crashes and you can't figure out why but at least you can try changing it until it stops crashing
  3. It works

I'm trying to create my own minimal server to debug the issue, already got the client joined the server (really, it was easy), but of course I can't figure out those chunks.

@robotman3000
Copy link
Owner Author

Perhaps we should enlist the help of one of the PocketMine-MP developers.

@MrPowerGamerBR
Copy link

@robotman3000 the problem is figuring out what fields are required for a chunk packet

I think it is like that:

Chunk X - VarInt
Chunk Z - VarInt
Number of sections in this chunk - Byte
Sections
??? - Byte (Nukkit always use 0 for this)
Blocks ID - Byte Array
Blocks Data - Byte Array
Blocks Sky Light - Byte Array
Blocks Light (? Probably light emitted from blocks like Glowstone) - Byte Array
End of Sections
Block Height (?) - Byte Array
? - Byte Array (Always 256 in Nukkit)
Biome ID Array - Byte Array
? - Byte (Always 0 in Nukkit)
Extra Data - Unsigned VarInt (Can be 0 if no extra data)
Block Entities - Byte Array

If you send everything, it should work.

Here is what I done (but didn't work)

		RakNetPacket rnp = new RakNetPacket(0xFE);
		rnp.writeByte(0x3a);
		try {
			VarInt.writeVarInt(rnp, 0); // Chunk X
			VarInt.writeVarInt(rnp, 0); // Chunk Z
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		rnp.writeByte((byte) 16); // Send all chunk sections
		int section = 0;
		while (16 > section) {
			rnp.writeByte((byte) 0); // Always zero
			byte[] array = new byte[4096];

			Arrays.fill(array, (byte) 1);
			String build = "";
			for (byte b : array) {
				build += b;
			}
			byte[] blocks = new byte[4096];
			byte[] data = new byte[2048];
			byte[] skyLight = new byte[2048];
			byte[] blockLight = new byte[2048];
			for (int x = 0; x < 16; x++) {
				for (int z = 0; z < 16; z++) {
					int i = (x << 7) | (z << 3);
					for (int y = 0; y < 16; y += 2) {
						blocks[(i << 1) | y] = (byte) 1;
						blocks[(i << 1) | (y + 1)] = (byte) 1;
						int b1 = 0;
						int b2 = 0;
						data[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
						b1 = 1;
						b2 = 1;
						skyLight[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
						b1 = 1;
						b2 = 1;
						blockLight[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
					}
				}
			}
			section++;
			ByteBuf bbx = Unpooled.buffer();
			bbx.writeBytes(blocks);
			bbx.writeBytes(data);
			bbx.writeBytes(skyLight);
			bbx.writeBytes(blockLight);
			rnp.write(bbx.array());
		}

		int height = 0;
		while (256 > height) {
			rnp.writeByte((byte) height);
			height++;
		}

		rnp.write(new byte[256]);
		rnp.write(new byte[1]);
		rnp.writeByte((byte) 0);
		try {
			VarInt.writeUnsignedVarInt(rnp, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		rnp.write(new byte[0]);
		packet = rnp;

The problem with MCPE development is the lack of a good, explained, protocol documentation, the PC version has a very extensive and good protocol documentation, the only similar thing that exists is yawk.at's MCPE documentation, but that's outdated since 0.15.

@MrPowerGamerBR
Copy link

6 days later and I still couldn't figure out how to send chunks

I tried doing this

package com.magicalpocket.network.packets;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;

import com.magicalpocket.utils.VarInt;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.marfgamer.jraknet.RakNetPacket;

public class FullChunkDataPacket extends DataPacket {
	public int x;
	public int z;
	
	@Override
	public void decode() {

	}

	@Override
	public void encode() {
		System.out.println("Chunk data...");

		RakNetPacket rnp = new RakNetPacket(0xFE);
		rnp.writeByte(0x3a);
		try {
			VarInt.writeVarInt(rnp, x); // Chunk X
			VarInt.writeVarInt(rnp, z); // Chunk Z
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        rnp.writeByte((byte) 16); // Chunk sections (?)
        for (int i = 0; i < 16; i++) {
            rnp.writeByte((byte) 0);

            ByteBuffer buffer = ByteBuffer.allocate(10240);
            byte[] blocks = new byte[4096];
            byte[] data = new byte[2048];
            byte[] skyLight = new byte[2048];
            byte[] blockLight = new byte[2048];
            for (int x = 0; x < 16; x++) {
                for (int z = 0; z < 16; z++) {
                    int temporary = (x << 7) | (z << 3);
                    for (int y = 0; y < 16; y += 2) {
                        blocks[(temporary << 1) | y] = (byte) 1;
                        blocks[(temporary << 1) | (y + 1)] = 1;
                        int b1 = 1;
                        int b2 = 1;
                        data[temporary | (y >> 1)] = (byte) ((b2 << 4) | b1);
                        b1 = 1;
                        b2 = 1;
                        skyLight[temporary | (y >> 1)] = (byte) ((b2 << 4) | b1);
                        b1 = 1;
                        b2 = 1;
                        blockLight[temporary | (y >> 1)] = (byte) ((b2 << 4) | b1);
                    }
                }
            }
            
            rnp.write(buffer
                    .put(blocks)
                    .put(data)
                    .put(skyLight)
                    .put(blockLight)
                    .array());
            
        }
        int[] heightMap = new int[256];
        Arrays.fill(heightMap, 1);
        for (int height : heightMap) {
            rnp.writeByte((byte) height);
        }
        rnp.write(new byte[256]);
        rnp.write(new byte[256]);
        rnp.writeByte((byte) 0);
        try {
			VarInt.writeUnsignedVarInt(rnp, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        rnp.write(new byte[0]);
		
		packet = rnp;
	}
}

But nope, didn't work.

@MrPowerGamerBR
Copy link

Tried replaying the data sent by Nukkit when sending a chunk and...

Also didn't work.

@robotman3000
Copy link
Owner Author

Try replaying an exact packet stream from Nukkit and slowly remove packets, to see what is required to get chunks to appear

@MrPowerGamerBR
Copy link

@robotman3000 I will try doing that later.

In theory, my code should work, but it doesn't.

package com.magicalpocket.network.packets;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import com.magicalpocket.utils.VarInt;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.marfgamer.jraknet.RakNetPacket;

public class FullChunkDataPacket extends DataPacket {
	public int x;
	public int z;
	
	@Override
	public void decode() {

	}

	@Override
	public void encode() {
		System.out.println("Chunk data...");

		RakNetPacket rnp = new RakNetPacket(0xFE);
		rnp.writeByte(0x3a);
		try {
			VarInt.writeVarInt(rnp, 0); // Chunk X
			VarInt.writeVarInt(rnp, 0); // Chunk Z
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Gson gson = new Gson();
		JsonReader reader;
		try {
			reader = new JsonReader(new FileReader("D:\\Minecraft Servers\\Nukkit\\nukkitdata.txt"));
			byte[] wow = gson.fromJson(reader, byte[].class);
			try {
				VarInt.writeUnsignedVarInt(rnp, wow.length);
				rnp.write(wow);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		packet = rnp;
	}
}

But nope, NOTHING happens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants