#Minecraft Chunk processing
1 messages · Page 1 of 1 (latest)
Fun, I have way too much experience in this particular topic
The idea here is modify packet that are sent to player
do you have any idea about it
I'm trying to flatten the bedrock layer or make every block from layer 0-4 all bedrock
That's easier to do with a chunk generator
There's no point in using client-sided blocks for this
it's janky
hmm the thing is
this is a proxy one :l
and everything I have access to is packet and server send and received
interesting
this is a folk of 2bored2wait
I'm making it to be abled to fake coordinate as well as doing other stuffs
Well
For spoofing bedrock and all
Yeah it's doable
I'd rather put the 4 layers as bedrock just to avoid any issues with uhh
breaking bedrock by accident
This could be ignore as if player reach a level of Y lower than 10 they will got disconnected
Yeh but for now I even not abled to modify it :l
I could do something like completely remove that bedrock layer
One's simple - Block change
There's also MultiBlockChange
and Chunk
Chunk in particular is the annoying one
:l yeh about chunk I’m really confused at it
you'll be doing a lot of processing :)
Not even knowing how to load it yet
And then after loading I even need to encode it once again :l
Hmm what are the numbers in chunkData refer to ?
It's weird
Each chunk has a palette
Which is just a "1 is air 2 is stone"
Then it sends chunk sections along with the palette
:l I don’t think so
It doesnt
It literally does
When I change 100 first blocks to 0 the whole chunk corrupted
Just look at the nms packet class
Maybe because it isn't as easy as setting 100 bytes
It was an array :l
The bytes contain the palette, size of the section etc
Could you have a look at this ^^
It is anvil chunk format I believe
:l Thank you but I really need a way to do it from scratch
as I need to rewrite it in js
I mean that you can get inspiration from that project
and in combination with wiki.vg it should be easily doable
It do confuse me a lots :l
in fact I already ready every wiki and docs that I could
but that doesn't seemed to include this format
that is a packet look like :l
it is a vector of data
and I have no idea to convert or modify it
On which Minecraft version do your servers run on? Chunk packets greatly differ with some versions
It is 1.12.2
https://wiki.vg/index.php?title=Protocol&oldid=13632#Chunk_Data (don't click on the links on the page, they will redirect you to 1.20)
https://wiki.vg/index.php?title=Chunk_Format&oldid=12959#Packet_structure (this is likely more helpful)
Could you explain that a bit
In the example
It is a 13 bits ?
While in this each entry is only 8?
What do you mean by 8
a byte (= int8) has 8 bits. a short (= int16) has 16 bits. an int(eger) (=int32) has 32bits. a long (=int64) has 64 bits
These are various data types that are being used within the packet format. The data that you are seeing is just a sequence of data types encoded into a byte array
If you want to read e.g. an integer, you will have to read 4 bytes of the byte array sequence and turn it into a number that your language understands using bitshifting
Using this concept you may find e.g. the following list on the wiki:
Int - Chunk X
Int - Chunk Y
In which case the bytes 1-4 in the byte array would stand for the x position and the bytes 5-8 for the y position
But in your case, the packet has already been decoded, hence you already see that information encoded within the json object that you gave us
However, the data field hasn't been encoded yet, which you'd have to implement yourself
You may look into the library that you are using and try to learn how they have been doing it
Note that this is not an easy task for a beginner. You very likely should just use a library that already did this for you.
:l actually not
That packet is decoded yes it is
But it is also an encoded one :l
For now I need to translate stuffs in chunkData into a vector of blocks to modify it
https://github.com/PrismarineJS/prismarine-chunk/tree/master/src/pc/1.9
He already did the work for you
There is a load method in which you can simply insert the fields from your packet as parameters
That code is build on top of https://github.com/PrismarineJS/node-minecraft-protocol which I guess you are using
@void scroll could you give me an example for that :l
just try to load this in but no luck :l
var column = new ChunkColumn()
var packet = { ... } // your packet from the example
column.load(packet.chunkData, packet.bitMap, true, packet.groundUp)
console.log(column.getBlock({ x:5, y:5 }))
This is how I'd try it. Never worked with it before and thus can't promise that it'd work
Looks pretty
:l
here the thing
I tried logging both stuffs
but they result in different result
complete
Are you working with the block ids from the correct version?
it is 1.12.2 :l
so I set the version to 1.12
and what did you do to have these blocks?
I did nothing
just only load it up
It is not a way to load It I believe
it create new instance
and by that time it create a new chunk :l
and the load is just replace some of its data I believed
@lethal narwhal could you provide any help at this :l
Ugh let's go over the byte format in 1.12
:l any reference to that
This is a bit confusing
And now that I'm re-reading this, it makes a lot more sense
So let's go over from the start
Packet's contents are:
-
Chunk x
-
Chunk z
-
Ground-up continuous (will leak memory, if you're sending new chunk data always set this to false)
-
Chunk section bitmask (right -> left is bottom -> top)
-
Size of the data array
-
The actual data array
-
Number of tile entities
-
The actual time entities
Chunk x and z are self explanatory
Ground-up continuous is explained on that post
The chunk section bitmask is like
Let's say that the first 3 chunk sections are empty, then the 3 bytes at the right are set to 0
Basically
int chunkX = readInt();
int chunkZ = readInt();
boolean groundUp = readBoolean();
List<ChunkSection> chunks = new ArrayList<>();
int mask = readInt();
int dataLength = readInt();
byte[] data = new byte[dataLength];
for(int index = 0; index < dataLength; index++) {
data[index] = readByte();
}
int tileLength = readInt();
NBTCompound[] tiles = new NBTCompound[tileLength];
for(int index = 0; index < tileLength; index++) {
tiles[index] = readNBT();
}
Now, we need to decipher the data
This is the contents of a chunk section
These contents are only sent for chunk section that are present in the bitmask, the sections are empty otherwise
1s what does readInt do :l
It reads an int from the incoming packet
Basic protocol stuff
Well in this case it's all varInt
Just grab the entire packet, make a read buffer out of it
:l so the packet now have
Only x z bitmask and a buffer of an array of lots of numbers
We have more than just xz bitmask and all
We have
X Z
Boolean
Int (bitmask)
Int (data length)
Byte array (data)
Int (tile entity count)
Array (nbt)
Here is the everything that the packet contains
Or well in your case you've managed to do all that parsing
Yeah so
You get the bitmap
It indicates what sections are present
31 is 0b00011111
Meaning the first 5 sections are sent and the top 3 aren't because they're empty
That is weird :l as I was testing to send half of the packet and half is void
And it does show full chunk
So I assume it send everything in a chunk
You could continue the last part
Still what in the chunkData refer to
In java this'd be something like
int mask = ...; // 31
int totalSections = 256 / 16; // build height / chunk section height
ChunkSection[] sections = new ChunkSection[totalSections];
for(int index = 0; index < totalSections; index++) {
boolean isChunkPresent = (mask >> index) & 1 == 1; // basically just see if this bit is present
if(!isChunkPresent) {
sections[index] = null; // empty section
continue;
}
sections[index] = readChunk();
}
The isChunkPresent thing is just a bitmask check
Let's say you have 00110011 as your bit mask
it'd return
0 -> true
1 -> true
2 -> false
3 -> false
4 -> true
5 -> true
Basically reading from right -> left and seeing if it's 1
Your readChunk method needs to be a sort of buffer, and you'll need to read bit by bit
And that goes something like
-
read the block palette length
-
If that palette length is above 9, you'll create a "direct palette"
-
otherwise, create an "indirect" palette
For the indirect palette:
- Read the palette size
- Create an array of that size
- Read the array
- Loop through the array, each index corresponds to a value in the "global" palette
But you have methods to get a blockstate from the global palette
So let's say you get an array of [1, 5, 3, 2], it means that:
- Id 0 on the local palette corresponds to 1 on the global palette
- Id 1 on the local palette corresponds to id 5 on the global palette
- Id 2 on the local palette corresponds to id 3 on the global palette
...
Ideally you'd make a palette class
It's basically a glorified list
So how that contruct data?
The data starts with a palette
And a number of bits per block
Then you gotta read those bits individually
also which encode is this :l?
11111 in bin is 31 but what is that 0b?
0b just stands for binary
oh
0x is hex
0 is just octal
so if you do 0123 it's octal but 123 is decimal
weird
so let start from this :l
(I like learning from example)
bitmap is 31 so it is 11111
Meaning the first 5 sections are there and the rest is air
the ChunkData shouldn't be seen as individual bytes but rather a long bit array
It's made to be used as a huge bit buffer
You start by reading the first number
Which is 5
That's the amount of bits per block on the first section
so there is 5 bits what is else :l?
5 bits per block
Then there's the palette
It's an indirect palette so you just gotta read the int array
Palette size is 24, and then the next 24 numbers are the palette
Then it's individual bit reading
Let's say you got this
4 bits per block
Palette size is 13
Palette is [0, 112, 16, 144, 9, 19, 21, 208, 2, 240, 1, 176, 1?]
I though the palette should be somethings like rectangle?
might be a weird encoding thing
Palette is not a rectangle
Palette is just a glorified list where it determines
0 is air
1 is stone
2 is dirt
So if you ask "What's the id of dirt?" it says 2
And if you ask "What's the block data of 2?" it says dirt
Basically a bimap
so from this what we do next :l? [0, 112, 16, 144, 9, 19, 21, 208, 2, 240, 1, 176, 1?]
That's our palette
compared to the global palette
You must have a global palette somewhere
? there is?
hmm so where to get it?
..
Hmm
@lethal narwhal
I got most of stuffs :l
but still really confuse
that is the chunk pallet
and that is the data
what does bit map here mean :l?
and also the chunk data
[4,4,0,112,48,32,128,2,17,17,17,17,17,.....]
it is 4 bits per block while the size is 4
so the array is [0,112,48,48]
which refered to
:l so after everything we have a new palette?
@lethal narwhal do you know where biome is store ?
I got in tro some trouble of this :l
in this case 17 refer to bedrock I believe
however there is only 32
while it should be 16*16 128
TLDR for this ?
TLDR?
Too Long Didn't Read
What is this about but in few sentences ?
I Need help in translate these
I want to decode that or at least get which represent to which