1use std::{cmp::Ordering, fmt, hash::Hasher};
2
3use azalea_buf::AzBuf;
4use crc32c::Crc32cHasher;
5use serde::{Serialize, ser};
6use thiserror::Error;
7use tracing::error;
8
9use crate::{registry_holder::RegistryHolder, resource_location::ResourceLocation};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, AzBuf)]
12pub struct Checksum(pub u32);
13
14pub struct ChecksumSerializer<'a, 'r> {
15 hasher: &'a mut Crc32cHasher,
16 registries: &'r RegistryHolder,
17}
18impl<'a, 'r> ChecksumSerializer<'a, 'r> {
19 pub fn checksum(&mut self) -> Checksum {
20 Checksum(self.hasher.finish() as u32)
21 }
22}
23
24impl<'a, 'r> ser::Serializer for ChecksumSerializer<'a, 'r> {
25 type Ok = ();
26
27 type Error = ChecksumError;
29
30 type SerializeSeq = ChecksumListSerializer<'a, 'r>;
31 type SerializeTuple = ChecksumListSerializer<'a, 'r>;
32 type SerializeTupleStruct = ChecksumListSerializer<'a, 'r>;
33 type SerializeTupleVariant = ChecksumMapSerializer<'a, 'r>;
34 type SerializeMap = ChecksumMapSerializer<'a, 'r>;
35 type SerializeStruct = ChecksumMapSerializer<'a, 'r>;
36 type SerializeStructVariant = ChecksumMapSerializer<'a, 'r>;
37
38 fn serialize_bool(self, v: bool) -> Result<()> {
39 assert!(self.hasher.finish() == 0);
40 self.hasher.write_u8(13);
41 self.hasher.write(&[v as u8]);
42 Ok(())
43 }
44
45 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
46 assert!(self.hasher.finish() == 0);
47 Ok(ChecksumMapSerializer {
48 hasher: self.hasher,
49 registries: self.registries,
50 entries: Vec::new(),
51 })
52 }
53 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
54 assert!(self.hasher.finish() == 0);
55 self.serialize_map(Some(len))
56 }
57
58 fn serialize_i8(self, v: i8) -> Result<()> {
59 assert!(self.hasher.finish() == 0);
60 self.hasher.write_u8(6);
61 self.hasher.write(&v.to_le_bytes());
62 Ok(())
63 }
64
65 fn serialize_i16(self, v: i16) -> Result<()> {
66 assert!(self.hasher.finish() == 0);
67 self.hasher.write_u8(7);
68 self.hasher.write(&v.to_le_bytes());
69 Ok(())
70 }
71
72 fn serialize_i32(self, v: i32) -> Result<()> {
73 assert!(self.hasher.finish() == 0);
74 self.hasher.write_u8(8);
75 self.hasher.write(&v.to_le_bytes());
76 Ok(())
77 }
78
79 fn serialize_i64(self, v: i64) -> Result<()> {
80 assert!(self.hasher.finish() == 0);
81 self.hasher.write_u8(9);
82 self.hasher.write(&v.to_le_bytes());
83 Ok(())
84 }
85
86 fn serialize_u8(self, v: u8) -> Result<()> {
87 assert!(self.hasher.finish() == 0);
88 self.serialize_i8(v as i8)
89 }
90
91 fn serialize_u16(self, v: u16) -> Result<()> {
92 assert!(self.hasher.finish() == 0);
93 self.serialize_i16(v as i16)
94 }
95
96 fn serialize_u32(self, v: u32) -> Result<()> {
97 assert!(self.hasher.finish() == 0);
98 self.serialize_i32(v as i32)
99 }
100
101 fn serialize_u64(self, v: u64) -> Result<()> {
102 assert!(self.hasher.finish() == 0);
103 self.serialize_i64(v as i64)
104 }
105
106 fn serialize_f32(self, v: f32) -> Result<()> {
107 assert!(self.hasher.finish() == 0);
108 self.hasher.write_u8(10);
109 self.hasher.write(&v.to_le_bytes());
110 Ok(())
111 }
112
113 fn serialize_f64(self, v: f64) -> Result<()> {
114 assert!(self.hasher.finish() == 0);
115 self.hasher.write_u8(11);
116 self.hasher.write(&v.to_le_bytes());
117 Ok(())
118 }
119
120 fn serialize_char(self, v: char) -> Result<()> {
121 assert!(self.hasher.finish() == 0);
122 self.serialize_u32(v as u32)
123 }
124
125 fn serialize_str(self, v: &str) -> Result<()> {
126 assert!(self.hasher.finish() == 0);
127 self.hasher.write_u8(12);
128 let utf16 = v.encode_utf16().collect::<Vec<_>>();
129 self.hasher.write(&(utf16.len() as u32).to_le_bytes());
130 for c in utf16 {
131 self.hasher.write(&c.to_le_bytes());
132 }
133 Ok(())
134 }
135
136 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
137 assert!(self.hasher.finish() == 0);
138 self.hasher.write_u8(14);
139 self.hasher.write(v);
140 self.hasher.write_u8(15);
141 Ok(())
142 }
143
144 fn serialize_none(self) -> Result<()> {
145 assert!(self.hasher.finish() == 0);
146 self.hasher.write_u8(1);
147 Ok(())
148 }
149
150 fn serialize_some<T>(self, value: &T) -> Result<()>
151 where
152 T: ?Sized + Serialize,
153 {
154 value.serialize(self)?;
157 Ok(())
158 }
159
160 fn serialize_unit(self) -> Result<()> {
161 assert!(self.hasher.finish() == 0);
162 Ok(())
163 }
164
165 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
166 assert!(self.hasher.finish() == 0);
167 update_hasher_for_map(self.hasher, &[]);
168 Ok(())
169 }
170
171 fn serialize_unit_variant(
172 self,
173 _name: &'static str,
174 _variant_index: u32,
175 variant: &'static str,
176 ) -> Result<()> {
177 self.serialize_str(variant)
178 }
179
180 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
181 where
182 T: ?Sized + Serialize,
183 {
184 value.serialize(self)
185 }
186
187 fn serialize_newtype_variant<T>(
188 self,
189 name: &'static str,
190 variant_index: u32,
191 _variant: &'static str,
192 value: &T,
193 ) -> Result<()>
194 where
195 T: ?Sized + Serialize,
196 {
197 if name.starts_with("minecraft:") {
200 let value = self
201 .registries
202 .map
203 .get(&ResourceLocation::from(name))
204 .and_then(|r| r.get_index(variant_index as usize))
205 .map(|r| r.0.to_string())
206 .unwrap_or_default();
207 self.serialize_str(&value)?;
208 return Ok(());
209 }
210
211 value.serialize(ChecksumSerializer {
212 hasher: self.hasher,
213 registries: self.registries,
214 })
215 }
216
217 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
218 assert!(self.hasher.finish() == 0);
219 Ok(ChecksumListSerializer {
220 hasher: self.hasher,
221 registries: self.registries,
222 values: Vec::with_capacity(len.unwrap_or_default()),
223 list_kind: ListKind::Normal,
224 })
225 }
226
227 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
228 assert!(self.hasher.finish() == 0);
229 Ok(ChecksumListSerializer {
230 hasher: self.hasher,
231 registries: self.registries,
232 values: Vec::with_capacity(len),
233 list_kind: ListKind::Normal,
234 })
235 }
236
237 fn serialize_tuple_struct(
238 self,
239 name: &'static str,
240 len: usize,
241 ) -> Result<Self::SerializeTupleStruct> {
242 assert!(self.hasher.finish() == 0);
243 let list_kind = if name == "azalea:int_array" {
244 self.hasher.write_u8(16);
245 ListKind::Int
246 } else if name == "azalea:long_array" {
247 self.hasher.write_u8(18);
248 ListKind::Long
249 } else {
250 ListKind::Normal
251 };
252 Ok(ChecksumListSerializer {
253 hasher: self.hasher,
254 registries: self.registries,
255 values: Vec::with_capacity(len),
256 list_kind,
257 })
258 }
259
260 fn serialize_tuple_variant(
261 self,
262 _name: &'static str,
263 _variant_index: u32,
264 _variant: &'static str,
265 len: usize,
266 ) -> Result<Self::SerializeTupleVariant> {
267 assert!(self.hasher.finish() == 0);
268 Ok(ChecksumMapSerializer {
269 hasher: self.hasher,
270 registries: self.registries,
271 entries: Vec::with_capacity(len),
272 })
273 }
274
275 fn serialize_struct_variant(
276 self,
277 _name: &'static str,
278 _variant_index: u32,
279 _variant: &'static str,
280 len: usize,
281 ) -> Result<Self::SerializeStructVariant> {
282 Ok(ChecksumMapSerializer {
283 hasher: self.hasher,
284 registries: self.registries,
285 entries: Vec::with_capacity(len),
286 })
287 }
288}
289
290pub struct ChecksumListSerializer<'a, 'r> {
291 hasher: &'a mut Crc32cHasher,
292 registries: &'r RegistryHolder,
293 values: Vec<Checksum>,
294 list_kind: ListKind,
297}
298impl<'a, 'r> ser::SerializeSeq for ChecksumListSerializer<'a, 'r> {
299 type Ok = ();
300 type Error = ChecksumError;
301
302 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
303 where
304 T: ?Sized + Serialize,
305 {
306 if self.list_kind == ListKind::Normal {
307 self.values.push(get_checksum(value, self.registries)?);
309 } else {
310 value.serialize(IntOrLongArrayChecksumSerializer {
311 hasher: self.hasher,
312 })?;
313 }
314
315 Ok(())
316 }
317
318 fn end(self) -> Result<()> {
319 match self.list_kind {
320 ListKind::Normal => {
321 assert!(self.hasher.finish() == 0);
322 update_hasher_for_list(self.hasher, &self.values);
323 }
324 ListKind::Int => {
325 self.hasher.write_u8(17);
326 }
327 ListKind::Long => {
328 self.hasher.write_u8(19);
329 }
330 }
331
332 Ok(())
333 }
334}
335#[derive(Default, PartialEq, Eq)]
340enum ListKind {
341 #[default]
342 Normal,
343 Int,
344 Long,
345}
346
347impl<'a, 'r> ser::SerializeTuple for ChecksumListSerializer<'a, 'r> {
348 type Ok = ();
349 type Error = ChecksumError;
350
351 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
352 where
353 T: ?Sized + Serialize,
354 {
355 ser::SerializeSeq::serialize_element(self, value)
356 }
357
358 fn end(self) -> Result<()> {
359 ser::SerializeSeq::end(self)
360 }
361}
362impl<'a, 'r> ser::SerializeTupleStruct for ChecksumListSerializer<'a, 'r> {
363 type Ok = ();
364 type Error = ChecksumError;
365
366 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
367 where
368 T: ?Sized + Serialize,
369 {
370 ser::SerializeSeq::serialize_element(self, value)
371 }
372
373 fn end(self) -> Result<()> {
374 ser::SerializeSeq::end(self)
375 }
376}
377
378pub struct ChecksumMapSerializer<'a, 'r> {
379 hasher: &'a mut Crc32cHasher,
381 registries: &'r RegistryHolder,
382 entries: Vec<(Checksum, Checksum)>,
384}
385impl<'a, 'r> ser::SerializeMap for ChecksumMapSerializer<'a, 'r> {
386 type Ok = ();
387 type Error = ChecksumError;
388
389 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
390 where
391 T: ?Sized + Serialize,
392 {
393 self.entries
395 .push((get_checksum(key, self.registries)?, Checksum(0)));
396 Ok(())
397 }
398
399 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
403 where
404 T: ?Sized + Serialize,
405 {
406 self.entries
408 .last_mut()
409 .expect("entry should've already been added")
410 .1 = get_checksum(value, self.registries)?;
411 Ok(())
412 }
413
414 fn end(self) -> Result<()> {
415 assert!(self.hasher.finish() == 0);
416 update_hasher_for_map(self.hasher, &self.entries);
417 Ok(())
418 }
419}
420impl<'a, 'r> ser::SerializeTupleVariant for ChecksumMapSerializer<'a, 'r> {
421 type Ok = ();
422 type Error = ChecksumError;
423
424 fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
425 where
426 T: ?Sized + Serialize,
427 {
428 error!("tuple variants are not supported when serializing checksums");
430 Ok(())
431 }
432
433 fn end(self) -> Result<()> {
434 assert!(self.hasher.finish() == 0);
435 Ok(())
436 }
437}
438impl<'a, 'r> ser::SerializeStruct for ChecksumMapSerializer<'a, 'r> {
439 type Ok = ();
440 type Error = ChecksumError;
441
442 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
443 where
444 T: ?Sized + Serialize,
445 {
446 self.entries.push((
447 get_checksum(key, self.registries)?,
448 get_checksum(value, self.registries)?,
449 ));
450 Ok(())
451 }
452
453 fn end(self) -> Result<()> {
454 assert!(self.hasher.finish() == 0);
455 update_hasher_for_map(self.hasher, &self.entries);
456 Ok(())
457 }
458}
459impl<'a, 'r> ser::SerializeStructVariant for ChecksumMapSerializer<'a, 'r> {
460 type Ok = ();
461 type Error = ChecksumError;
462
463 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
464 where
465 T: ?Sized + Serialize,
466 {
467 self.entries.push((
468 get_checksum(key, self.registries)?,
469 get_checksum(value, self.registries)?,
470 ));
471 Ok(())
472 }
473
474 fn end(self) -> Result<()> {
475 assert!(self.hasher.finish() == 0);
476 update_hasher_for_map(self.hasher, &self.entries);
477 Ok(())
478 }
479}
480
481struct IntOrLongArrayChecksumSerializer<'a> {
483 hasher: &'a mut Crc32cHasher,
484}
485impl<'a> ser::Serializer for IntOrLongArrayChecksumSerializer<'a> {
486 type Ok = ();
487 type Error = ChecksumError;
488 type SerializeSeq = ChecksumListSerializer<'a, 'a>;
490 type SerializeTuple = ChecksumListSerializer<'a, 'a>;
491 type SerializeTupleStruct = ChecksumListSerializer<'a, 'a>;
492 type SerializeTupleVariant = ChecksumMapSerializer<'a, 'a>;
493 type SerializeMap = ChecksumMapSerializer<'a, 'a>;
494 type SerializeStruct = ChecksumMapSerializer<'a, 'a>;
495 type SerializeStructVariant = ChecksumMapSerializer<'a, 'a>;
496
497 fn serialize_bool(self, _v: bool) -> Result<()> {
498 unimplemented!()
499 }
500 fn serialize_i8(self, _v: i8) -> Result<()> {
501 unimplemented!()
502 }
503 fn serialize_i16(self, _v: i16) -> Result<()> {
504 unimplemented!()
505 }
506 fn serialize_i32(self, v: i32) -> Result<()> {
507 self.hasher.write(&v.to_le_bytes());
508 Ok(())
509 }
510 fn serialize_i64(self, v: i64) -> Result<()> {
511 self.hasher.write(&v.to_le_bytes());
512 Ok(())
513 }
514 fn serialize_u8(self, _v: u8) -> Result<()> {
515 unimplemented!()
516 }
517 fn serialize_u16(self, _v: u16) -> Result<()> {
518 unimplemented!()
519 }
520 fn serialize_u32(self, v: u32) -> Result<()> {
521 self.serialize_i32(v as i32)
522 }
523 fn serialize_u64(self, v: u64) -> Result<()> {
524 self.serialize_i64(v as i64)
525 }
526 fn serialize_f32(self, _v: f32) -> Result<()> {
527 unimplemented!()
528 }
529 fn serialize_f64(self, _v: f64) -> Result<()> {
530 unimplemented!()
531 }
532 fn serialize_char(self, _v: char) -> Result<()> {
533 unimplemented!()
534 }
535 fn serialize_str(self, _v: &str) -> Result<()> {
536 unimplemented!()
537 }
538 fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
539 unimplemented!()
540 }
541 fn serialize_none(self) -> Result<()> {
542 unimplemented!()
543 }
544 fn serialize_some<T>(self, _v: &T) -> Result<()>
545 where
546 T: ?Sized + Serialize,
547 {
548 unimplemented!()
549 }
550 fn serialize_unit(self) -> Result<()> {
551 unimplemented!()
552 }
553 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
554 unimplemented!()
555 }
556 fn serialize_unit_variant(
557 self,
558 _name: &'static str,
559 _variant_index: u32,
560 _variant: &'static str,
561 ) -> Result<()> {
562 unimplemented!()
563 }
564 fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
565 where
566 T: ?Sized + Serialize,
567 {
568 unimplemented!()
569 }
570 fn serialize_newtype_variant<T>(
571 self,
572 _name: &'static str,
573 _variant_index: u32,
574 _variant: &'static str,
575 _value: &T,
576 ) -> Result<()>
577 where
578 T: ?Sized + Serialize,
579 {
580 unimplemented!()
581 }
582 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
583 unimplemented!()
584 }
585 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
586 unimplemented!()
587 }
588 fn serialize_tuple_struct(
589 self,
590 _name: &'static str,
591 _len: usize,
592 ) -> Result<Self::SerializeTupleStruct> {
593 unimplemented!()
594 }
595 fn serialize_tuple_variant(
596 self,
597 _name: &'static str,
598 _variant_index: u32,
599 _variant: &'static str,
600 _len: usize,
601 ) -> Result<Self::SerializeTupleVariant> {
602 unimplemented!()
603 }
604 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
605 unimplemented!()
606 }
607 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
608 unimplemented!()
609 }
610 fn serialize_struct_variant(
611 self,
612 _name: &'static str,
613 _variant_index: u32,
614 _variant: &'static str,
615 _len: usize,
616 ) -> Result<Self::SerializeStructVariant> {
617 unimplemented!()
618 }
619}
620
621#[derive(Error, Debug)]
622#[error("Checksum serialization error")]
623pub struct ChecksumError;
624impl ser::Error for ChecksumError {
625 fn custom<T>(msg: T) -> Self
626 where
627 T: fmt::Display,
628 {
629 eprintln!("Serialization error: {msg}");
630 ChecksumError
631 }
632}
633type Result<T> = std::result::Result<T, ChecksumError>;
634
635pub fn get_checksum<T: Serialize + ?Sized>(
636 value: &T,
637 registries: &RegistryHolder,
638) -> Result<Checksum> {
639 let mut hasher = Crc32cHasher::default();
640 value.serialize(ChecksumSerializer {
641 hasher: &mut hasher,
642 registries,
643 })?;
644 Ok(Checksum(hasher.finish() as u32))
645}
646
647fn update_hasher_for_list(h: &mut Crc32cHasher, values: &[Checksum]) {
648 h.write_u8(4);
649 for v in values {
650 h.write(&v.0.to_le_bytes());
651 }
652 h.write_u8(5);
653}
654fn update_hasher_for_map(h: &mut Crc32cHasher, entries: &[(Checksum, Checksum)]) {
655 h.write_u8(2);
656 let mut entries = entries.to_vec();
657 entries.sort_by(|a, b| match a.0.cmp(&b.0) {
658 Ordering::Equal => a.1.cmp(&b.1),
659 other => other,
660 });
661 for (k, v) in entries {
662 h.write(&k.0.to_le_bytes());
663 h.write(&v.0.to_le_bytes());
664 }
665 h.write_u8(3);
666}