(self, save: &impl OdbReader, storage: &mut impl OdbWriter)
| 146 | } |
| 147 | |
| 148 | fn flatten(self, save: &impl OdbReader, storage: &mut impl OdbWriter) -> Result<Vec<String>> { |
| 149 | let mut processed = Vec::new(); |
| 150 | for pattern in FLATTEN_PATTERNS { |
| 151 | for key in save.glob(pattern)? { |
| 152 | log::info!("Process entities region file {key}"); |
| 153 | let data = save.get(&key)?; |
| 154 | let filename = key.split('/').next_back().unwrap_or(""); |
| 155 | let (region_x, region_z) = parse_xz(filename) |
| 156 | .with_context(|| format!("failed to parse region coordinates from {key}"))?; |
| 157 | let Some((timestamp_header, chunks)) = |
| 158 | read_region(Cursor::new(data), region_x, region_z) |
| 159 | .with_context(|| format!("failed to read region from {key}"))? |
| 160 | else { |
| 161 | processed.push(key); |
| 162 | continue; |
| 163 | }; |
| 164 | storage.put(&format!("{key}/timestamp-header"), ×tamp_header)?; |
| 165 | |
| 166 | // Parse and sort all chunk NBTs |
| 167 | let mut result: Vec<(i32, i32, NbtCompound)> = chunks |
| 168 | .into_iter() |
| 169 | .map(|(chunk_x, chunk_z, raw_bytes)| { |
| 170 | let mut nbt = load_nbt(Cursor::new(&raw_bytes)) |
| 171 | .context("failed to load chunk nbt")? |
| 172 | .as_compound(); |
| 173 | promote_entity_fields(&mut nbt)?; |
| 174 | sort_entity_attributes_by_id(&mut nbt); |
| 175 | Ok((chunk_x, chunk_z, nbt)) |
| 176 | }) |
| 177 | .collect::<Result<Vec<_>>>()?; |
| 178 | |
| 179 | // Sort by (cz, cx) for deterministic ordering |
| 180 | result |
| 181 | .sort_unstable_by(|(cx1, cz1, ..), (cx2, cz2, ..)| (cz1, cx1).cmp(&(cz2, cx2))); |
| 182 | |
| 183 | // Build and write entities.nbt with Chunks + Flatten compounds |
| 184 | { |
| 185 | let mut chunks_compound = NbtCompound::new(); |
| 186 | let mut all_motions = Vec::new(); |
| 187 | let mut all_positions = Vec::new(); |
| 188 | let mut all_rotations = Vec::new(); |
| 189 | for (chunk_x, chunk_z, nbt) in &mut result { |
| 190 | let key_str = format!("c.{}.{}", chunk_x, chunk_z); |
| 191 | // Extract flattened arrays from chunk and aggregate into Flatten |
| 192 | if let Some(m) = nbt |
| 193 | .remove("Motions") |
| 194 | .and_then(|t| t.into_list()) |
| 195 | .and_then(|l| l.into_doubles()) |
| 196 | { |
| 197 | all_motions.extend(m); |
| 198 | } |
| 199 | if let Some(p) = nbt |
| 200 | .remove("Pos") |
| 201 | .and_then(|t| t.into_list()) |
| 202 | .and_then(|l| l.into_doubles()) |
| 203 | { |
| 204 | all_positions.extend(p); |
| 205 | } |
nothing calls this directly
no test coverage detected