Closed AlexisHuvier closed 5 years ago
There's some docs coming for this soon, but you want something like:
def send_chunk(self, x, z, full, heightmap, sections, biomes, block_entities):
self.send_packet(
'chunk_data',
self.buff_type.pack('ii?', x, z, full),
self.buff_type.pack_chunk_bitmask(sections),
self.buff_type.pack_nbt(heightmap), # added in 1.14
self.buff_type.pack_chunk(sections, biomes),
self.buff_type.pack_varint(len(block_entities)),
b"".join(self.buff_type.pack_nbt(entity) for entity in block_entities))
sections
should be a python list with 16 elements, where each element is either None
(an all-air chunk) or a 3-tuple of (blocks, block_light, sky_light)
. The blocks
element is an instance of BlockArray
, the others will be either PackedArray
or None
depending on your dimension and the MC version. You can create an empty BlockArray
via BlockArray.empty()
Thanks :D
I have some problem : First, pack_chunk_bitmask doesn't exist for the 1.14 Buffer Second, What is heightmap ? A list of int ? For the end, what is biomes ?
Thanks for all
First, pack_chunk_bitmask doesn't exist for the 1.14 Buffer
Try using the latest master
.
Second, What is heightmap ? A list of int ?
It's an NBT tag, something like TagRoot --> TagCompound --> TagLongArray. The TagCompound has elements like "MOTION_BLOCKING"
. You'll probably want to check what vanilla MC does, either by checking out the contents of an .mca
file or using a proxy.
For the end, what is biomes ?
List of 256 integers, corresponding to biome IDs for the 16x16 (x, z) chunk
With the latest master, i have a error :
Traceback (most recent call last):
File "D:/Programmation/Python/Projet/PyMine/PyMine/PyMine.py", line 1, in <module>
from Core import Factory
File "D:\Programmation\Python\Projet\PyMine\PyMine\Core\__init__.py", line 1, in <module>
from Core.Protocol import Protocol
File "D:\Programmation\Python\Projet\PyMine\PyMine\Core\Protocol.py", line 1, in <module>
from quarry.net.server import ServerProtocol
File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\net\server.py", line 5, in <module>
from quarry.net.protocol import Factory, Protocol, ProtocolError, \
File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\net\protocol.py", line 5, in <module>
from quarry.types.buffer import BufferUnderrun, buff_types
File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\types\buffer\__init__.py", line 6, in <module>
from quarry.types.buffer.v1_9 import Buffer1_9
File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\types\buffer\v1_9.py", line 2, in <module>
from quarry.types.chunk import PackedArray, BlockArray
File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\types\chunk.py", line 2, in <module>
from bitstring import BitArray, Bits
ModuleNotFoundError: No module named 'bitstring'
pip install bitstring
Last question. I have some region file (.mca). How use "RegionFile" to send map to players ?
TBH I should look into adding that as core functionality, as it's pretty fiddly. I'll get back to you.
Yes, it will be interesting to add this.
If you want some help, im here
On second thought, I'm inclined not to add it to the core just to keep chunk handling in quarry nice and generic.
Roughly you'll need to:
my_region_file.load_chunk()
. This will give you an NBT tag.tag.body["Level"].value["Heightmaps"]
.Bear in mind you might want to keep some chunks in-memory rather than loading from disk each time.
You'll need to construct the sections
list yourself. You can use BlockArray.from_nbt()
and pass a section tag (i.e. a TagCompound
containing a "BlockStates"
field) for each section present in the NBT. I think something like this should work:
sections = [None] * 16
for section in level.value["Sections"].value:
y = section.value["Y"].value
sections[y] = BlockArray.from_nbt(section)
You might not want to send all sections in the chunk to the client.
With this code, i have an error : File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\types\chunk.py", line 330, in from_nbt nbt_palette = section.value['Palette'] builtins.KeyError: 'Palette'
Could you print(section)
?
TagCompound({'SkyLight': TagByteArray(<PackedArray len=4096 sector=8 value=4 fresh=0 twiddled=0>), 'Y': TagByte(-1)})
I suppose you need to add a condition like:
if 0 <= y < 16:
sections[y] = ...
I think light-only sections were added in 1.14. See also here
I made a fix but i have an other error : File "C:\Users\LavaPower\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quarry\types\buffer\v1_9.py", line 31, in pack_chunk_bitmask if section and not section[0].is_empty(): builtins.AttributeError: 'dict' object has no attribute 'is_empty'
Sorry, one more try:
sections = [None] * 16
for section in level.value["Sections"].value:
y = section.value["Y"].value
if 0 <= y < 16:
blocks = BlockArray.from_nbt(section)
block_light = None
sky_light = None
sections[y] = (blocks, block_light, sky_light)
Basically you want the section to be a 3-tuple
Probably you need to embed the heightmap compound in a TagRoot
. You can use the TagRoot.from_body()
constructor for this purpose.
It works ! Thanks you !
Hello.
I want to create a empty chunk but i don't know how use chunk_data packet...
Can you help me ?