1mod serialize;
6mod from_stream;
7
8use flate2::read::GzDecoder;
9use flate2::write::GzEncoder;
10use flate2::Compression;
11use from_stream::{i16_fs, i64_fs, str_fs, u16_fs, u32_fs};
12use serialize::{Deserializer,DeserializeError};
13
14use std::fs::{read, File, OpenOptions};
15use std::io::{Read, Write};
16use std::path::PathBuf;
17
18use thiserror::Error;
19
20#[derive(Default,Clone)]
21pub struct Level {
22 pub blocks: Option<Vec<u8>>, pub version: Option<u8>, pub name: Option<String>, pub creator: Option<String>, pub createTime: Option<i64>, pub width: Option<i32>, pub height: Option<i32>, pub depth: Option<i32>, pub xSpawn: Option<i32>, pub ySpawn: Option<i32>, pub zSpawn: Option<i32>, pub rotSpawn: Option<f32>, pub tickCount: Option<i32>, pub unprocessed: Option<i32>, pub entities: Option<Vec<Entity>>, pub networkMode: Option<bool>, pub cloudColor: Option<i32>, pub fogColor: Option<i32>, pub skyColor: Option<i32>, pub waterLevel: Option<i32>, pub player: Option<Player>, pub creativeMode: Option<bool>, pub growTrees: Option<bool> }
50
51impl Level {
52 pub fn new () -> Self {
53 Level {
54 blocks: None,
55 version: None,
56 name: None,
57 creator: None,
58 createTime: None,
59 width: None,
60 height: None,
61 depth: None,
62 xSpawn: None,
63 ySpawn: None,
64 zSpawn: None,
65 rotSpawn: None,
66 tickCount: None,
67 unprocessed: None,
68 entities: None,
69 networkMode: None,
70 cloudColor: None,
71 fogColor: None,
72 skyColor: None,
73 waterLevel: None,
74 player: None,
75 creativeMode: None,
76 growTrees: None
77 }
78 }
79}
80
81#[derive(Clone)]
82pub enum Entity {
83 Sheep(Sheep),
84 Pig(Pig),
85 Creeper(Creeper),
86 Zombie(Zombie),
87 Skeleton(Skeleton),
88 Spider(Spider),
89 Item(Item),
90 Arrow(Arrow),
91 PrimedTnt(PrimedTnt),
92 Sign(Sign),
93 Smolder(Smolder),
94 Player(Player)
95}
96
97impl Entity {
98 pub fn get_sheep (&self) -> Result<Sheep,ClassicError> {
99 match self {
100 Entity::Sheep(value) => Ok(value.clone()),
101 _ => Err(ClassicError::InvalidEntity())
102 }
103 }
104
105 pub fn get_pig (&self) -> Result<Pig,ClassicError> {
106 match self {
107 Entity::Pig(value) => Ok(value.clone()),
108 _ => Err(ClassicError::InvalidEntity())
109 }
110 }
111
112 pub fn get_creeper (&self) -> Result<Creeper,ClassicError> {
113 match self {
114 Entity::Creeper(value) => Ok(value.clone()),
115 _ => Err(ClassicError::InvalidEntity())
116 }
117 }
118
119 pub fn get_zombie (&self) -> Result<Zombie,ClassicError> {
120 match self {
121 Entity::Zombie(value) => Ok(value.clone()),
122 _ => Err(ClassicError::InvalidEntity())
123 }
124 }
125
126 pub fn get_skeleton (&self) -> Result<Skeleton,ClassicError> {
127 match self {
128 Entity::Skeleton(value) => Ok(value.clone()),
129 _ => Err(ClassicError::InvalidEntity())
130 }
131 }
132
133 pub fn get_spider (&self) -> Result<Spider,ClassicError> {
134 match self {
135 Entity::Spider(value) => Ok(value.clone()),
136 _ => Err(ClassicError::InvalidEntity())
137 }
138 }
139
140 pub fn get_item (&self) -> Result<Item,ClassicError> {
141 match self {
142 Entity::Item(value) => Ok(value.clone()),
143 _ => Err(ClassicError::InvalidEntity())
144 }
145 }
146
147 pub fn get_arrow (&self) -> Result<Arrow,ClassicError> {
148 match self {
149 Entity::Arrow(value) => Ok(value.clone()),
150 _ => Err(ClassicError::InvalidEntity())
151 }
152 }
153
154 pub fn get_primed_tnt (&self) -> Result<PrimedTnt,ClassicError> {
155 match self {
156 Entity::PrimedTnt(value) => Ok(value.clone()),
157 _ => Err(ClassicError::InvalidEntity())
158 }
159 }
160
161 pub fn get_sign (&self) -> Result<Sign,ClassicError> {
162 match self {
163 Entity::Sign(value) => Ok(value.clone()),
164 _ => Err(ClassicError::InvalidEntity())
165 }
166 }
167
168 pub fn get_smolder (&self) -> Result<Smolder,ClassicError> {
169 match self {
170 Entity::Smolder(value) => Ok(value.clone()),
171 _ => Err(ClassicError::InvalidEntity())
172 }
173 }
174
175 pub fn get_player (&self) -> Result<Player,ClassicError> {
176 match self {
177 Entity::Player(value) => Ok(value.clone()),
178 _ => Err(ClassicError::InvalidEntity())
179 }
180 }
181
182}
183
184#[derive(Clone)]
185pub struct EntityFields {
186 pub bbHeight: Option<f32>,
187 pub bbWidth: Option<f32>,
188 pub collision: Option<bool>,
189 pub fallDistance: Option<f32>,
190 pub footSize: Option<f32>,
191 pub heightOffset: Option<f32>,
192 pub horizontalCollision: Option<bool>,
193 pub hovered: Option<bool>,
194 pub makeStepSound: Option<bool>,
195 pub nextStep: Option<i32>,
196 pub noPhysics: Option<bool>,
197 pub onGround: Option<bool>,
198 pub pushthrough: Option<f32>,
199 pub removed: Option<bool>,
200 pub slide: Option<bool>,
201 pub textureId: Option<i32>,
202 pub walkDist: Option<f32>,
203 pub walkDistO: Option<f32>,
204 pub x: Option<f32>,
205 pub xOld: Option<f32>,
206 pub xRot: Option<f32>,
207 pub xRotO: Option<f32>,
208 pub xd: Option<f32>,
209 pub xo: Option<f32>,
210 pub y: Option<f32>,
211 pub yOld: Option<f32>,
212 pub yRot: Option<f32>,
213 pub yRotO: Option<f32>,
214 pub ySlideOffset: Option<f32>,
215 pub yd: Option<f32>,
216 pub yo: Option<f32>,
217 pub z: Option<f32>,
218 pub zOld: Option<f32>,
219 pub zd: Option<f32>,
220 pub zo: Option<f32>,
221 pub bb: Option<AABB>
222}
223
224impl EntityFields {
225 pub fn new() -> Self {
226 EntityFields {
227 bbHeight: None,
228 bbWidth: None,
229 collision: None,
230 fallDistance: None,
231 footSize: None,
232 heightOffset: None,
233 horizontalCollision: None,
234 hovered: None,
235 makeStepSound: None,
236 nextStep: None,
237 noPhysics: None,
238 onGround: None,
239 pushthrough: None,
240 removed: None,
241 slide: None,
242 textureId: None,
243 walkDist: None,
244 walkDistO: None,
245 x: None,
246 xOld: None,
247 xRot: None,
248 xRotO: None,
249 xd: None,
250 xo: None,
251 y: None,
252 yOld: None,
253 yRot: None,
254 yRotO: None,
255 ySlideOffset: None,
256 yd: None,
257 yo: None,
258 z: None,
259 zOld: None,
260 zd: None,
261 zo: None,
262 bb: None
263 }
264 }
265}
266
267#[derive(Clone)]
268pub struct Mob {
269 pub airSupply: Option<i32>,
270 pub allowAlpha: Option<bool>,
271 pub animStep: Option<f32>,
272 pub animStepO: Option<f32>,
273 pub attackTime: Option<i32>,
274 pub bobStrength: Option<f32>,
275 pub dead: Option<bool>,
276 pub deathScore: Option<i32>,
277 pub deathTime: Option<i32>,
278 pub hasHair: Option<bool>,
279 pub health: Option<i32>,
280 pub hurtDir: Option<f32>,
281 pub hurtDuration: Option<i32>,
282 pub hurtTime: Option<i32>,
283 pub invulnerableDuration: Option<i32>,
284 pub invulnerableTime: Option<i32>,
285 pub lastHealth: Option<i32>,
286 pub oRun: Option<f32>,
287 pub oTilt: Option<f32>,
288 pub renderOffset: Option<f32>,
289 pub rot: Option<f32>,
290 pub rotA: Option<f32>,
291 pub rotOffs: Option<f32>,
292 pub run: Option<f32>,
293 pub speed: Option<f32>,
294 pub tickCount: Option<i32>,
295 pub tilt: Option<f32>,
296 pub timeOffs: Option<f32>,
297 pub yBodyRot: Option<f32>,
298 pub yBodyRotO: Option<f32>,
299 pub ai: Option<AI>,
300 pub modelName: Option<String>,
301 pub textureName: Option<String>,
302 pub entity: Option<EntityFields>
303}
304
305impl Mob {
306 pub fn new() -> Self {
307 Mob {
308 airSupply: None,
309 allowAlpha: None,
310 animStep: None,
311 animStepO: None,
312 attackTime: None,
313 bobStrength: None,
314 dead: None,
315 deathScore: None,
316 deathTime: None,
317 hasHair: None,
318 health: None,
319 hurtDir: None,
320 hurtDuration: None,
321 hurtTime: None,
322 invulnerableDuration: None,
323 invulnerableTime: None,
324 lastHealth: None,
325 oRun: None,
326 oTilt: None,
327 renderOffset: None,
328 rot: None,
329 rotA: None,
330 rotOffs: None,
331 run: None,
332 speed: None,
333 tickCount: None,
334 tilt: None,
335 timeOffs: None,
336 yBodyRot: None,
337 yBodyRotO: None,
338 ai: None,
339 modelName: None,
340 textureName: None,
341 entity: None
342 }
343 }
344}
345
346#[derive(Clone)]
347pub struct QuadrapedMob {
348 pub mob: Mob
349}
350
351#[derive(Clone)]
352pub struct HumanoidMob {
353 pub armor: bool,
354 pub helmet: bool,
355 pub mob: Mob
356}
357
358#[derive(Clone)]
359pub struct Sheep {
360 pub graze: f32,
361 pub grazeO: f32,
362 pub grazing: bool,
363 pub grazingTime: i32,
364 pub hasFur: bool,
365 pub quadrapedMob: QuadrapedMob
366}
367
368#[derive(Clone)]
369pub struct Pig {
370 pub quadrapedMob: QuadrapedMob
371}
372
373#[derive(Clone)]
374pub struct Creeper {
375 pub mob: Mob
376}
377
378#[derive(Clone)]
379pub struct Zombie {
380 pub humanoidMob: HumanoidMob
381}
382
383#[derive(Clone)]
384pub struct Skeleton {
385 pub zombie: Zombie
386}
387
388#[derive(Clone)]
389pub struct Spider {
390 pub quadrapedMob: QuadrapedMob
391}
392
393#[derive(Clone)]
394pub struct Player {
395 pub arrows: i32,
396 pub bob: f32,
397 pub oBob: f32,
398 pub score: i32,
399 pub userType: u8,
400 pub inventory: Inventory,
401 pub mob: Mob
402}
403
404#[derive(Clone)]
405pub struct Item {
406 pub age: i32,
407 pub resource: i32,
408 pub rot: f32,
409 pub tickCount: i32,
410 pub xd: f32,
411 pub yd: f32,
412 pub zd: f32,
413 pub entity: EntityFields
414}
415
416#[derive(Clone)]
417pub struct Arrow {
418 pub damage: i32,
419 pub gravity: f32,
420 pub hasHilt: bool,
421 pub stickTime: i32,
422 pub time: i32,
423 pub atype: i32,
424 pub xRot: f32,
425 pub xRotO: f32,
426 pub xd: f32,
427 pub yRot: f32,
428 pub yRotO: f32,
429 pub yd: f32,
430 pub zd: f32,
431 pub owner: Box<Option<Entity>>,
432 pub entity: EntityFields
433}
434
435#[derive(Clone)]
436pub struct PrimedTnt {
437 pub life: i32,
438 pub xd: f32,
439 pub yd: f32,
440 pub zd: f32,
441 pub entity: EntityFields
442}
443
444#[derive(Clone)]
445pub struct Sign {
446 pub rot: f32,
447 pub xd: f32,
448 pub yd: f32,
449 pub zd: f32,
450 pub messages: Vec<String>,
451 pub entity: EntityFields
452}
453
454#[derive(Clone)]
455pub struct Smolder {
456 pub life: i32,
457 pub lifeTime: i32,
458 pub entity: EntityFields
459}
460
461#[derive(Clone)]
462pub struct AABB {
463 pub epsilon: f32,
464 pub x0: f32,
465 pub x1: f32,
466 pub y0: f32,
467 pub y1: f32,
468 pub z0: f32,
469 pub z1: f32
470}
471
472#[derive(Clone)]
473pub struct AI {
474 pub damage: i32,
475 pub attackDelay: i32,
476 pub jumping: bool,
477 pub noActionTime: i32,
478 pub runSpeed: f32,
479 pub xxa: f32,
480 pub yRotA: f32,
481 pub yya: f32,
482 pub attackTarget: Box<Option<Entity>>,
483 pub mob: String,
484 pub random: Random1
485}
486
487#[derive(Clone)]
488pub struct Random1 {
489 pub haveNextNextGaussian: bool,
490 pub nextNextGaussian: f64,
491 pub seed: i64
492}
493
494#[derive(Clone)]
495pub struct Inventory {
496 pub selected: i32,
497 pub count: Vec<i32>,
498 pub popTime: Vec<i32>,
499 pub slots: Vec<i32>
500}
501
502#[derive(Error, Debug)]
503
504pub enum ClassicError {
505 #[error("Error Deserializing")]
506 DeserializeError(#[from] DeserializeError),
507
508 #[error("Classic Level Not Recognized")]
509 LevelNotRecognized(),
510
511 #[error("Unrecognized main class, expected `com.mojang.minecraft.level.Level`, but found {0}")]
512 InvalidClass(String),
513
514 #[error("File format not supported, expected 0-2 but found {0}")]
515 InvalidFileFormat(u8),
516
517 #[error("Unexpected Entity: {0}")]
518 UnexpectedEntity(String),
519
520 #[error("Invalid Entity Request")]
521 InvalidEntity(),
522
523 #[error("Unsupported Feature (Coming soon!)")]
524 UnsupportedFeature(),
525}
526
527pub fn read_level (file: PathBuf) -> Result <Level, ClassicError> {
532 let stream: Vec<u8> = read(file).unwrap();
534 let mut d_stream = GzDecoder::new(&stream[..]);
535 let mut bytes: Vec<u8> = Vec::new();
536 d_stream.read_to_end(&mut bytes).unwrap();
537
538 let magic_number: u32 = u32_fs(0, &bytes[..]);
540
541 if magic_number != 0x271BB788 {return Ok(pre_classic_to_level(bytes))}
543
544 if bytes[4] == 1 {return Ok(classic_13_to_level(bytes))}
546
547 if bytes[4] == 2 {return Ok(classic_to_level(bytes)?)}
549
550 return Err(ClassicError::LevelNotRecognized())
551
552}
553
554pub fn write_level (level: Level, path: String, format: u8) -> Result <(), ClassicError> {
559 match format {
560 0 => level_to_pre_classic(level, path)?,
561 1 => level_to_classic_13(level, path)?,
562 2 => {
563 return Err(ClassicError::UnsupportedFeature())
565 },
566 _ => return Err(ClassicError::InvalidFileFormat(format))
567 }
568
569 return Ok(())
570}
571
572pub fn pre_classic_to_level (bytes: Vec<u8>) -> Level {
578 let mut level: Level = Level::new();
579 level.blocks = Some(bytes);
580 return level;
581}
582
583pub fn level_to_pre_classic (level: Level, path: String) -> Result<(), ClassicError> {
588 let name: &str = if path == "" {"level.dat"} else {"/level.dat"};
589
590 let mut tiles: Vec<u8> = level.blocks.unwrap();
591 while tiles.len() > 256 * 64 * 256 {tiles.pop();}
593
594 let output= OpenOptions::new()
595 .write(true)
596 .create(true)
597 .open(path + name)
598 .unwrap();
599
600 let mut encoder = GzEncoder::new(output, Compression::default());
601 encoder.write_all(&tiles).unwrap();
602
603 Ok(())
604}
605
606pub fn classic_13_to_level (bytes: Vec<u8>) -> Level {
612 let mut buf: usize = 4;
613 let mut level: Level = Level::new();
614
615 level.version = Some(bytes[buf]);
617 buf += 1;
618
619 let mut sh: u16 = u16_fs(buf, &bytes[..]);
621 buf += 2;
622 level.name = Some(str_fs(buf, &bytes[..], sh as i32));
623 buf += sh as usize;
624
625 sh = u16_fs(buf, &bytes[..]);
627 buf += 2;
628 level.creator = Some(str_fs(buf, &bytes[..], sh as i32));
629 buf += sh as usize;
630
631 level.createTime = Some(i64_fs(buf, &bytes[..]));
633 buf += 8;
634
635 level.width = Some(i16_fs(buf, &bytes[..]) as i32);
637 buf += 2;
638 level.height = Some(i16_fs(buf, &bytes[..]) as i32);
639 buf += 2;
640 level.depth = Some(i16_fs(buf, &bytes[..]) as i32);
641 buf += 2;
642
643 let mut tile_map: Vec<u8> = Vec::new();
645 for i in buf..bytes.len() as usize {
646 tile_map.push(bytes[i as usize]);
647 }
648
649 level.blocks = Some(tile_map);
650
651 return level;
652
653}
654
655pub fn level_to_classic_13(level: Level, path: String) -> Result<(),ClassicError> {
659 let mut bytes: Vec<u8> = Vec::new();
660
661 let magic_number: u32 = 0x271BB788;
663 bytes.extend_from_slice(&magic_number.to_be_bytes());
664 if level.version.is_some() {bytes.push(level.version.unwrap())} else {bytes.push(1)}
665
666 let name = if level.name.is_some() {level.name.unwrap()} else {String::from("A Nice World")};
668 let len = name.len() as u16;
669 bytes.extend_from_slice(&len.to_be_bytes());
670 bytes.extend_from_slice(name.as_bytes());
671 let creator = if level.creator.is_some() {level.creator.unwrap()} else {String::from("noname")};
676 let len = creator.len() as u16;
677 bytes.extend_from_slice(&len.to_be_bytes());
678 bytes.extend_from_slice(creator.as_bytes());
679 if level.createTime.is_some() {
684 bytes.extend_from_slice(&level.createTime.unwrap().to_be_bytes())
685 } else {
686 bytes.extend_from_slice(&(0 as i64).to_be_bytes())
687 }
688
689 if level.width.is_some() {
691 bytes.extend_from_slice(&(level.width.unwrap() as i16).to_be_bytes())
692 } else {
693 bytes.extend_from_slice(&(256 as i16).to_be_bytes())
694 }
695 if level.height.is_some() {
696 bytes.extend_from_slice(&(level.height.unwrap() as i16).to_be_bytes())
697 } else {
698 bytes.extend_from_slice(&(256 as i16).to_be_bytes())
699 }
700 if level.depth.is_some() {
701 bytes.extend_from_slice(&(level.depth.unwrap() as i16).to_be_bytes())
702 } else {
703 bytes.extend_from_slice(&(64 as i16).to_be_bytes())
704 }
705
706 if level.blocks.is_some() {
708 for tile in level.blocks.unwrap() {bytes.push(tile)}
709 }
710
711 let output= OpenOptions::new()
713 .write(true)
714 .create(true)
715 .open(path)
716 .unwrap();
717
718 let mut encoder = GzEncoder::new(output, Compression::default());
720 encoder.write_all(&bytes).unwrap();
721
722 Ok(())
723}
724
725pub fn classic_to_level (bytes: Vec<u8>) -> Result<Level, ClassicError> {
731
732 let mut buf: usize = 4;
734 let mut level: Level = Level::new();
735
736 level.version = Some(bytes[buf as usize]);
737 buf += 1;
738
739 let mut deserializer: Deserializer = Deserializer::new();
741 let contents: Vec<serialize::Object> = deserializer.deserialize(&bytes[buf..])?;
742
743 if contents.len() != 1 { return Err(ClassicError::DeserializeError(DeserializeError::InvalidContentLength(1, contents.len()))) }
745
746 let object: serialize::NewObject = contents[0].get_new_object()?;
747
748 let class_info: serialize::NewClassDesc = object.class_desc.get_new_class_desc()?;
750 let class_data: serialize::ClassData = object.class_data.unwrap();
751
752 if class_info.class_name != "com.mojang.minecraft.level.Level" {
753 return Err(ClassicError::InvalidClass(class_info.class_name.clone()))
754 }
755
756 let fields: serialize::Fields = class_info.class_desc_info.unwrap().fields;
757 let values: Vec<serialize::Value> = class_data.values;
758
759 for i in 0..fields.count as usize {
761 match fields.field_descs[i].get_field_name()?.as_str() {
762 "createTime" => { level.createTime = Some(values[i].get_long()?) },
763 "depth" => { level.depth = Some(values[i].get_integer()?) },
764 "height" => { level.height = Some(values[i].get_integer()?) },
765 "rotSpawn" => { level.rotSpawn = Some(values[i].get_float()?) },
766 "tickCount" => { level.tickCount = Some(values[i].get_integer()?) },
767 "unprocessed" => { level.unprocessed = Some(values[i].get_integer()?) },
768 "width" => { level.width = Some(values[i].get_integer()?) },
769 "xSpawn" => { level.xSpawn = Some(values[i].get_integer()?) },
770 "ySpawn" => { level.zSpawn = Some(values[i].get_integer()?) },
771 "zSpawn" => { level.ySpawn = Some(values[i].get_integer()?) },
772 "networkMode" => { level.networkMode = Some(values[i].get_boolean()?) },
773 "cloudColor" => { level.cloudColor = Some(values[i].get_integer()?) },
774 "fogColor" => { level.fogColor = Some(values[i].get_integer()?) },
775 "skyColor" => { level.skyColor = Some(values[i].get_integer()?) },
776 "waterLevel" => { level.waterLevel = Some(values[i].get_integer()?) },
777 "creativeMode" => { level.creativeMode = Some(values[i].get_boolean()?) },
778 "growTrees" => { level.growTrees = Some(values[i].get_boolean()?) },
779 "blocks" => {
780 let wrapped: Vec<serialize::Value> = values[i].get_array()?;
781 let mut blocks: Vec<u8> = Vec::new();
782 for value in wrapped {
783 blocks.push(value.get_byte()?)
784 }
785 level.blocks = Some(blocks);
786 },
787 "creator" => {
788 level.creator = values[i].get_object()?.get_new_string()?.string;
789 },
790 "name" => {
791 level.name = values[i].get_object()?.get_new_string()?.string;
792 },
793 "entities" => (), "blockMap" => {
795
796 let block_map: serialize::NewObject = values[i].get_object()?.get_new_object()?;
798 let field_descs: Vec<serialize::FieldDesc> = block_map.class_desc.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs;
799 let values1: Vec<serialize::Value> = block_map.class_data.unwrap().values;
800
801 let mut entity_grid: Vec<serialize::Value> = Vec::new();
803 for i in 0..field_descs.len() {
804 if field_descs[i].get_field_name()? == "all" {
805 entity_grid = values1[i].clone().get_object()?.get_new_object()?.class_data.unwrap().values[1].get_array()?;
806 }
807 }
808
809 let mut entities: Vec<Entity> = Vec::new();
811 for entity in entity_grid {
812 match parse_entity(entity.get_object()?.get_new_object()?) {
813 Ok(val) => {
814 entities.push(val.clone());
815 if matches!(val.clone(), Entity::Player(_)) {
816 level.player = Some(val.get_player()?);
817 }
818 },
819 Err(e) => println!("Entity Parsing Failed: {e}")
820 }
821 }
822 level.entities = Some(entities);
823 },
824 "player" => {
825 if level.player.is_none() {
828 match parse_entity(values[i].get_object()?.get_new_object()?) {
829 Ok (val) => level.player = Some(val.get_player()?),
830 Err(e) => println!("Player Parsing Failed: {e}")
831 }
832 }
833 },
834 _ => println!("Unexpected Field: {}", fields.field_descs[i].get_field_name()?.as_str())
835
836 }
837 }
838
839 Ok(level)
840}
841
842fn parse_entity (entity: serialize::NewObject) -> Result<Entity,ClassicError> {
843 let name: String = entity.class_desc.get_new_class_desc()?.class_name;
844 let classes: Vec<&str> = name.split(".").collect();
845 let values: Vec<serialize::Value> = entity.class_data.unwrap().values;
846 let mut field_descs: Vec<Vec<serialize::FieldDesc>> = Vec::new();
847 field_descs.push(entity.class_desc.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs);
848 let mut super_class: Box<serialize::ClassDesc> = entity.class_desc.get_new_class_desc()?.class_desc_info.unwrap().super_class_desc;
849 while !matches!(*super_class, serialize::ClassDesc::Null) {
850 field_descs.push(super_class.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs);
851 super_class = super_class.get_new_class_desc()?.class_desc_info.unwrap().super_class_desc;
852 }
853 let mut entity_fields: EntityFields = EntityFields::new();
854 let mut index: usize = 0;
855 for field in field_descs[field_descs.len()-1].clone() {
856 match field.get_field_name()?.as_str() {
857 "bbHeight" => entity_fields.bbHeight = Some(values[index].get_float()?),
858 "bbWidth" => entity_fields.bbWidth = Some(values[index].get_float()?),
859 "collision" => entity_fields.collision = Some(values[index].get_boolean()?),
860 "fallDistance" => entity_fields.fallDistance = Some(values[index].get_float()?),
861 "footSize" => entity_fields.footSize = Some(values[index].get_float()?),
862 "heightOffset" => entity_fields.heightOffset = Some(values[index].get_float()?),
863 "horizontalCollision" => entity_fields.horizontalCollision = Some(values[index].get_boolean()?),
864 "hovered" => entity_fields.hovered = Some(values[index].get_boolean()?),
865 "makeStepSound" => entity_fields.makeStepSound = Some(values[index].get_boolean()?),
866 "nextStep" => entity_fields.nextStep = Some(values[index].get_integer()?),
867 "noPhysics" => entity_fields.noPhysics = Some(values[index].get_boolean()?),
868 "onGround" => entity_fields.onGround = Some(values[index].get_boolean()?),
869 "pushthrough" => entity_fields.pushthrough = Some(values[index].get_float()?),
870 "removed" => entity_fields.removed = Some(values[index].get_boolean()?),
871 "slide" => entity_fields.slide = Some(values[index].get_boolean()?),
872 "textureId" => entity_fields.textureId = Some(values[index].get_integer()?),
873 "walkDist" => entity_fields.walkDist = Some(values[index].get_float()?),
874 "walkDistO" => entity_fields.walkDistO = Some(values[index].get_float()?),
875 "x" => entity_fields.x = Some(values[index].get_float()?),
876 "xOld" => entity_fields.xOld = Some(values[index].get_float()?),
877 "xRot" => entity_fields.xRot = Some(values[index].get_float()?),
878 "xRotO" => entity_fields.xRotO = Some(values[index].get_float()?),
879 "xd" => entity_fields.xd = Some(values[index].get_float()?),
880 "xo" => entity_fields.xo = Some(values[index].get_float()?),
881 "y" => entity_fields.y = Some(values[index].get_float()?),
882 "yOld" => entity_fields.yOld = Some(values[index].get_float()?),
883 "yRot" => entity_fields.yRot = Some(values[index].get_float()?),
884 "yRotO" => entity_fields.yRotO = Some(values[index].get_float()?),
885 "ySlideOffset" => entity_fields.ySlideOffset = Some(values[index].get_float()?),
886 "yd" => entity_fields.yd = Some(values[index].get_float()?),
887 "yo" => entity_fields.yo = Some(values[index].get_float()?),
888 "z" => entity_fields.z = Some(values[index].get_float()?),
889 "zOld" => entity_fields.zOld = Some(values[index].get_float()?),
890 "zd" => entity_fields.zd = Some(values[index].get_float()?),
891 "zo" => entity_fields.zo = Some(values[index].get_float()?),
892 "bb" => {
893 let aabb_vals: Vec<serialize::Value> = values[index].get_object()?.get_new_object()?.class_data.unwrap().values;
894 let aabb: AABB = AABB {
895 epsilon: aabb_vals[0].get_float()?,
896 x0: aabb_vals[1].get_float()?,
897 x1: aabb_vals[2].get_float()?,
898 y0: aabb_vals[3].get_float()?,
899 y1: aabb_vals[4].get_float()?,
900 z0: aabb_vals[5].get_float()?,
901 z1: aabb_vals[6].get_float()?
902 };
903 entity_fields.bb = Some(aabb);
904 },
905 "blockMap" => (),
906 "level" => (),
907 _ => println!("Unexpected entity field found: {}", field.get_field_name()?.as_str())
908 }
909 index += 1;
910 }
911 if classes[3] == "mob" || classes[3] == "player" {
912 let mut mob: Mob = Mob::new();
913 mob.entity = Some(entity_fields);
914 for field in field_descs[field_descs.len()-2].clone() {
915 match field.get_field_name()?.as_str() {
916 "airSupply" => mob.airSupply = Some(values[index].get_integer()?),
917 "allowAlpha" => mob.allowAlpha = Some(values[index].get_boolean()?),
918 "animStep" => mob.animStep = Some(values[index].get_float()?),
919 "animStepO" => mob.animStepO = Some(values[index].get_float()?),
920 "attackTime" => mob.attackTime = Some(values[index].get_integer()?),
921 "bobStrength" => mob.bobStrength = Some(values[index].get_float()?),
922 "dead" => mob.dead = Some(values[index].get_boolean()?),
923 "deathScore" => mob.deathScore = Some(values[index].get_integer()?),
924 "deathTime" => mob.deathTime = Some(values[index].get_integer()?),
925 "hasHair" => mob.hasHair = Some(values[index].get_boolean()?),
926 "health" => mob.health = Some(values[index].get_integer()?),
927 "hurtDir" => mob.hurtDir = Some(values[index].get_float()?),
928 "hurtDuration" => mob.hurtDuration = Some(values[index].get_integer()?),
929 "hurtTime" => mob.hurtTime = Some(values[index].get_integer()?),
930 "invulnerableDuration" => mob.invulnerableDuration = Some(values[index].get_integer()?),
931 "invulnerableTime" => mob.invulnerableTime = Some(values[index].get_integer()?),
932 "lastHealth" => mob.lastHealth = Some(values[index].get_integer()?),
933 "oRun" => mob.oRun = Some(values[index].get_float()?),
934 "oTilt" => mob.oTilt = Some(values[index].get_float()?),
935 "renderOffset" => mob.renderOffset = Some(values[index].get_float()?),
936 "rot" => mob.rot = Some(values[index].get_float()?),
937 "rotA" => mob.rotA = Some(values[index].get_float()?),
938 "rotOffs" => mob.rotOffs = Some(values[index].get_float()?),
939 "run" => mob.run = Some(values[index].get_float()?),
940 "speed" => mob.speed = Some(values[index].get_float()?),
941 "tickCount" => mob.tickCount = Some(values[index].get_integer()?),
942 "tilt" => mob.tilt = Some(values[index].get_float()?),
943 "timeOffs" => mob.timeOffs = Some(values[index].get_float()?),
944 "yBodyRot" => mob.yBodyRot = Some(values[index].get_float()?),
945 "yBodyRotO" => mob.yBodyRotO = Some(values[index].get_float()?),
946 "ai" => {
947 let ai_vals: Vec<serialize::Value> = values[index].get_object()?.get_new_object()?.class_data.unwrap().values;
948 let random_vals: Vec<serialize::Value> = ai_vals[11].get_object()?.get_new_object()?.class_data.unwrap().values;
949 let random: Random1 = Random1 {
950 haveNextNextGaussian: random_vals[0].get_boolean()?,
951 nextNextGaussian: random_vals[1].get_double()?,
952 seed: random_vals[2].get_long()?
953 };
954 let att_tar: Option<Entity> = match ai_vals[8].get_object()? {
955 serialize::Object::NewObject(_) => match parse_entity(ai_vals[8].get_object()?.get_new_object()?) {
956 Ok (val) => Some(val),
957 Err(e) => {
958 println!("Error Handling Target of {name}: {e}");
959 None
960 }
961 },
962 _ => None
963 };
964 let ai: AI = AI {
965 damage: ai_vals[0].get_integer()?,
966 attackDelay: ai_vals[1].get_integer()?,
967 jumping: ai_vals[2].get_boolean()?,
968 noActionTime: ai_vals[3].get_integer()?,
969 runSpeed: ai_vals[4].get_float()?,
970 xxa: ai_vals[5].get_float()?,
971 yRotA: ai_vals[6].get_float()?,
972 yya: ai_vals[7].get_float()?,
973 attackTarget: Box::new(att_tar),
974 mob: name.clone(),
975 random: random
976 };
977 mob.ai = Some(ai);
978 },
979 "modelName" => mob.modelName = Some(values[index].get_object()?.get_new_string()?.string.unwrap()),
980 "textureName" => mob.textureName = Some(values[index].get_object()?.get_new_string()?.string.unwrap()),
981 _ => println!("Unexpected mob field found: {}", field.get_field_name()?.as_str())
982 }
983 index += 1;
984 }
985 match classes[4] {
986 "Sheep" => {
987 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
988 let sheep: Sheep = Sheep {
989 graze: values[index].get_float()?,
990 grazeO: values[index + 1].get_float()?,
991 grazing: values[index + 2].get_boolean()?,
992 grazingTime: values[index + 3].get_integer()?,
993 hasFur: values[index + 4].get_boolean()?,
994 quadrapedMob: quadraped_mob
995 };
996 return Ok(Entity::Sheep(sheep))
997 },
998 "Pig" => {
999 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
1000 let pig: Pig = Pig { quadrapedMob: quadraped_mob };
1001 return Ok(Entity::Pig(pig))
1002 },
1003 "Creeper" => {
1004 let creeper: Creeper = Creeper { mob: mob };
1005 return Ok(Entity::Creeper(creeper))
1006 },
1007 "Zombie" => {
1008 let humanoid_mob: HumanoidMob = HumanoidMob {
1009 armor: values[index].get_boolean()?,
1010 helmet: values[index + 1].get_boolean()?,
1011 mob: mob
1012 };
1013 let zombie: Zombie = Zombie { humanoidMob: humanoid_mob };
1014 return Ok(Entity::Zombie(zombie))
1015 },
1016 "Skeleton" => {
1017 let humanoid_mob: HumanoidMob = HumanoidMob {
1018 armor: values[index].get_boolean()?,
1019 helmet: values[index + 1].get_boolean()?,
1020 mob: mob
1021 };
1022 let zombie: Zombie = Zombie { humanoidMob: humanoid_mob };
1023 let skeleton: Skeleton = Skeleton { zombie: zombie };
1024 return Ok(Entity::Skeleton(skeleton))
1025 },
1026 "Spider" => {
1027 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
1028 let spider: Spider = Spider { quadrapedMob: quadraped_mob };
1029 return Ok (Entity::Spider(spider))
1030 },
1031 "Player" => {
1032 let inv_vals: Vec<serialize::Value> = values[index + 5].get_object()?.get_new_object()?.class_data.unwrap().values;
1033 let mut arrs: Vec<Vec<i32>> = Vec::new();
1034 for i in 1..inv_vals.len() {
1035 let mut arr: Vec<i32> = Vec::new();
1036 for val in inv_vals[i].get_array()? {
1037 arr.push(val.get_integer()?);
1038 }
1039 arrs.push(arr);
1040 }
1041 let inventory: Inventory = Inventory {
1042 selected: inv_vals[0].get_integer()?,
1043 count: arrs[0].clone(),
1044 popTime: arrs[1].clone(),
1045 slots: arrs[2].clone(),
1046 };
1047 let player: Player = Player {
1048 arrows: values[index].get_integer()?,
1049 bob: values[index + 1].get_float()?,
1050 oBob: values[index + 2].get_float()?,
1051 score: values[index + 3].get_integer()?,
1052 userType: values[index + 4].get_byte()?,
1053 inventory: inventory,
1054 mob: mob
1055 };
1056 return Ok(Entity::Player(player.clone()))
1057 },
1058 _ => return Err(ClassicError::UnexpectedEntity(name))
1059 }
1060 } else {
1061 match classes[4] {
1062 "Arrow" => {
1063 let owner: Option<Entity> = match values[index + 13].get_object()? {
1064 serialize::Object::NewObject(_) => match parse_entity(values[index + 13].get_object()?.get_new_object()?) {
1065 Ok (val) => Some(val),
1066 Err(e) => {
1067 println!("Error Handling Target of {name}: {e}");
1068 None
1069 }
1070 },
1071 _ => None
1072 };
1073 let arrow: Arrow = Arrow {
1074 damage: values[index].get_integer()?,
1075 gravity: values[index + 1].get_float()?,
1076 hasHilt: values[index + 2].get_boolean()?,
1077 stickTime: values[index + 3].get_integer()?,
1078 time: values[index + 4].get_integer()?,
1079 atype: values[index + 5].get_integer()?,
1080 xRot: values[index + 6].get_float()?,
1081 xRotO: values[index + 7].get_float()?,
1082 xd: values[index + 8].get_float()?,
1083 yRot: values[index + 9].get_float()?,
1084 yRotO: values[index + 10].get_float()?,
1085 yd: values[index + 11].get_float()?,
1086 zd: values[index + 12].get_float()?,
1087 owner: Box::new(owner),
1088 entity: entity_fields
1089 };
1090 return Ok(Entity::Arrow(arrow))
1091 },
1092 "Item" => {
1093 let item: Item = Item {
1094 age: values[index].get_integer()?,
1095 resource: values[index + 1].get_integer()?,
1096 rot: values[index + 2].get_float()?,
1097 tickCount: values[index + 3].get_integer()?,
1098 xd: values[index + 4].get_float()?,
1099 yd: values[index + 5].get_float()?,
1100 zd: values[index + 6].get_float()?,
1101 entity: entity_fields
1102 };
1103 return Ok(Entity::Item(item));
1104 },
1105 "PrimedTnt" => {
1106 let primed_tnt: PrimedTnt = PrimedTnt {
1107 life: values[index].get_integer()?,
1108 xd: values[index + 1].get_float()?,
1109 yd: values[index + 2].get_float()?,
1110 zd: values[index + 3].get_float()?,
1111 entity: entity_fields
1112 };
1113 return Ok(Entity::PrimedTnt(primed_tnt))
1114 },
1115 "Sign" => {
1116 let mut arr: Vec<String> = Vec::new();
1117 for str in values[index + 4].get_array()? {
1118 arr.push(str.get_object()?.get_new_string()?.string.unwrap())
1119 }
1120 let sign: Sign = Sign {
1121 rot: values[index].get_float()?,
1122 xd: values[index + 1].get_float()?,
1123 yd: values[index + 2].get_float()?,
1124 zd: values[index + 3].get_float()?,
1125 messages: arr,
1126 entity: entity_fields
1127 };
1128 return Ok(Entity::Sign(sign))
1129 }
1130 "fx" => {
1131 let smolder: Smolder = Smolder {
1132 life: values[index].get_integer()?,
1133 lifeTime: values[index + 1].get_integer()?,
1134 entity: entity_fields
1135 };
1136 return Ok(Entity::Smolder(smolder))
1137 },
1138 _ => return Err(ClassicError::UnexpectedEntity(name))
1139 }
1140 }
1141}