nurtex_protocol/types/
heightmap.rs1use nurtex_codec::Buffer;
2use nurtex_codec::types::variable::VarI32;
3use nurtex_codec::{read_byte, read_bytes};
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct HeightmapsRaw {
8 pub bytes: Vec<u8>,
9}
10
11#[derive(Clone, Debug, PartialEq)]
13pub struct NbtRaw {
14 pub bytes: Vec<u8>,
15}
16
17impl HeightmapsRaw {
18 fn remaining(buffer: &std::io::Cursor<&[u8]>) -> usize {
19 buffer.get_ref().len().saturating_sub(buffer.position() as usize)
20 }
21
22 fn read_nbt_raw(buffer: &mut std::io::Cursor<&[u8]>) -> Option<Vec<u8>> {
23 let start = buffer.position() as usize;
24
25 let tag_id = read_byte(buffer)?;
26 if tag_id != 0x0A {
27 return None;
28 }
29
30 let name_len = u16::read_buf(buffer)? as usize;
31 let _ = read_bytes(buffer, name_len)?;
32
33 loop {
34 let id = read_byte(buffer)?;
35 if id == 0 {
36 break;
37 }
38
39 let name_len = u16::read_buf(buffer)? as usize;
40 let _ = read_bytes(buffer, name_len)?;
41 skip_nbt_payload(buffer, id)?;
42 }
43
44 let end = buffer.position() as usize;
45 Some(buffer.get_ref()[start..end].to_vec())
46 }
47
48 fn read_map_raw(buffer: &mut std::io::Cursor<&[u8]>) -> Option<Vec<u8>> {
49 let start = buffer.position() as usize;
50
51 let map_size = i32::read_var(buffer)? as usize;
52 for _ in 0..map_size {
53 let _key = i32::read_var(buffer)?;
54 let len = i32::read_var(buffer)? as usize;
55 for _ in 0..len {
56 let _ = i64::read_buf(buffer)?;
57 }
58 }
59
60 let end = buffer.position() as usize;
61 Some(buffer.get_ref()[start..end].to_vec())
62 }
63}
64
65impl Buffer for HeightmapsRaw {
66 fn read_buf(buffer: &mut std::io::Cursor<&[u8]>) -> Option<Self> {
67 if Self::remaining(buffer) == 0 {
68 return Some(Self { bytes: vec![] });
69 }
70
71 let pos = buffer.position() as usize;
72 let first = *buffer.get_ref().get(pos)?;
73
74 let bytes = if first == 0x0A { Self::read_nbt_raw(buffer)? } else { Self::read_map_raw(buffer)? };
75
76 Some(Self { bytes })
77 }
78
79 fn write_buf(&self, buffer: &mut impl std::io::Write) -> std::io::Result<()> {
80 buffer.write_all(&self.bytes)
81 }
82}
83
84impl Buffer for NbtRaw {
85 fn read_buf(buffer: &mut std::io::Cursor<&[u8]>) -> Option<Self> {
86 if HeightmapsRaw::remaining(buffer) == 0 {
87 return Some(Self { bytes: vec![] });
88 }
89
90 let start = buffer.position() as usize;
91 let tag_id = read_byte(buffer)?;
92 if tag_id == 0 {
93 let end = buffer.position() as usize;
94 return Some(Self {
95 bytes: buffer.get_ref()[start..end].to_vec(),
96 });
97 }
98
99 let name_len = u16::read_buf(buffer)? as usize;
100 let _ = read_bytes(buffer, name_len)?;
101 skip_nbt_payload(buffer, tag_id)?;
102
103 let end = buffer.position() as usize;
104 Some(Self {
105 bytes: buffer.get_ref()[start..end].to_vec(),
106 })
107 }
108
109 fn write_buf(&self, buffer: &mut impl std::io::Write) -> std::io::Result<()> {
110 buffer.write_all(&self.bytes)
111 }
112}
113
114fn skip_nbt_payload(buffer: &mut std::io::Cursor<&[u8]>, tag_id: u8) -> Option<()> {
116 match tag_id {
117 1 => {
118 let _ = i8::read_buf(buffer)?;
119 }
120 2 => {
121 let _ = i16::read_buf(buffer)?;
122 }
123 3 => {
124 let _ = i32::read_buf(buffer)?;
125 }
126 4 => {
127 let _ = i64::read_buf(buffer)?;
128 }
129 5 => {
130 let _ = f32::read_buf(buffer)?;
131 }
132 6 => {
133 let _ = f64::read_buf(buffer)?;
134 }
135 7 => {
136 let len = i32::read_buf(buffer)? as usize;
137 let _ = read_bytes(buffer, len)?;
138 }
139 8 => {
140 let len = u16::read_buf(buffer)? as usize;
141 let _ = read_bytes(buffer, len)?;
142 }
143 9 => {
144 let child_id = read_byte(buffer)?;
145 let len = i32::read_buf(buffer)? as usize;
146 for _ in 0..len {
147 skip_nbt_payload(buffer, child_id)?;
148 }
149 }
150 10 => loop {
151 let id = read_byte(buffer)?;
152 if id == 0 {
153 break;
154 }
155 let name_len = u16::read_buf(buffer)? as usize;
156 let _ = read_bytes(buffer, name_len)?;
157 skip_nbt_payload(buffer, id)?;
158 },
159 11 => {
160 let len = i32::read_buf(buffer)? as usize;
161 let _ = read_bytes(buffer, len * 4)?;
162 }
163 12 => {
164 let len = i32::read_buf(buffer)? as usize;
165 let _ = read_bytes(buffer, len * 8)?;
166 }
167 _ => return None,
168 }
169
170 Some(())
171}