67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
import io
|
|
import unittest
|
|
|
|
from minecraft.networking.modern import (
|
|
PaletteSection, SectionBlocksUpdatePacket,
|
|
)
|
|
from minecraft.networking.packets import PacketBuffer
|
|
from minecraft.networking.types import Long, VarInt, VarLong
|
|
|
|
from mosfet.info import blocks
|
|
from mosfet.protocol.managers import ChunkColumn, WorldState
|
|
|
|
|
|
def encode_section_update(section_x, section_y, section_z, changes):
|
|
"""Encode Prismarine's section-position and packed x:z:y records."""
|
|
buffer = PacketBuffer()
|
|
packed_section = (
|
|
((section_x & 0x3FFFFF) << 42) |
|
|
((section_z & 0x3FFFFF) << 20) |
|
|
(section_y & 0xFFFFF))
|
|
if packed_section >= (1 << 63):
|
|
packed_section -= 1 << 64
|
|
Long.send(packed_section, buffer)
|
|
VarInt.send(len(changes), buffer)
|
|
for x, y, z, block_id in changes:
|
|
local = ((x & 0xF) << 8) | ((z & 0xF) << 4) | (y & 0xF)
|
|
VarLong.send((block_id << 12) | local, buffer)
|
|
packet = SectionBlocksUpdatePacket()
|
|
packet.read(io.BytesIO(buffer.get_writable()))
|
|
return packet
|
|
|
|
|
|
class TestSectionBlockUpdates(unittest.TestCase):
|
|
def test_negative_section_coordinates_and_local_yz_decode(self):
|
|
bed_id = next(iter(blocks.BED_IDS))
|
|
packet = encode_section_update(
|
|
-11, 4, -20, [(3, 6, 9, bed_id)])
|
|
|
|
self.assertEqual(packet.id, 0x56)
|
|
self.assertEqual(packet.changes, [(-173, 70, -311, bed_id)])
|
|
|
|
def test_section_update_replaces_old_block_and_index_entry(self):
|
|
section_x, section_y, section_z = -11, 4, -20
|
|
x, y, z = -173, 70, -311
|
|
bed_id = next(iter(blocks.BED_IDS))
|
|
world = WorldState(min_y=section_y * 16)
|
|
world.chunks[(section_x, section_z)] = ChunkColumn(
|
|
section_x, section_z,
|
|
[{'blocks': PaletteSection(0, [blocks.AIR], [], 4096)}],
|
|
section_y)
|
|
|
|
placed = encode_section_update(
|
|
section_x, section_y, section_z, [(x, y, z, bed_id)])
|
|
world.handle_section_update(placed)
|
|
self.assertEqual(world.get_block_at(x, y, z), bed_id)
|
|
self.assertIn((x, y, z), world.index[bed_id])
|
|
|
|
broken = encode_section_update(
|
|
section_x, section_y, section_z, [(x, y, z, blocks.AIR)])
|
|
world.handle_section_update(broken)
|
|
self.assertEqual(world.get_block_at(x, y, z), blocks.AIR)
|
|
self.assertNotIn((x, y, z), world.index.get(bed_id, set()))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|