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(transparent)]
506 FileNotFound(#[from] std::io::Error),
507
508 #[error("Error Deserializing")]
509 DeserializeError(#[from] DeserializeError),
510
511 #[error("Classic Level Not Recognized")]
512 LevelNotRecognized(),
513
514 #[error("Unrecognized main class, expected `com.mojang.minecraft.level.Level`, but found {0}")]
515 InvalidClass(String),
516
517 #[error("File format not supported, expected 0-2 but found {0}")]
518 InvalidFileFormat(u8),
519
520 #[error("Unexpected Entity: {0}")]
521 UnexpectedEntity(String),
522
523 #[error("Invalid Entity Request")]
524 InvalidEntity(),
525
526 #[error("Unsupported Feature (Coming soon!)")]
527 UnsupportedFeature(),
528}
529
530pub fn read_level (file: PathBuf) -> Result <Level, ClassicError> {
535 let stream: Vec<u8> = read(file)?;
537 let mut d_stream = GzDecoder::new(&stream[..]);
538 let mut bytes: Vec<u8> = Vec::new();
539 d_stream.read_to_end(&mut bytes).unwrap();
540
541 let magic_number: u32 = u32_fs(0, &bytes[..]);
543
544 if magic_number != 0x271BB788 {return Ok(pre_classic_to_level(bytes))}
546
547 if bytes[4] == 1 {return Ok(classic_13_to_level(bytes))}
549
550 if bytes[4] == 2 {return Ok(classic_to_level(bytes)?)}
552
553 return Err(ClassicError::LevelNotRecognized())
554
555}
556
557pub fn write_level (level: Level, path: String, format: u8) -> Result <(), ClassicError> {
562 match format {
563 0 => level_to_pre_classic(level, path)?,
564 1 => level_to_classic_13(level, path)?,
565 2 => {
566 return Err(ClassicError::UnsupportedFeature())
568 },
569 _ => return Err(ClassicError::InvalidFileFormat(format))
570 }
571
572 return Ok(())
573}
574
575pub fn pre_classic_to_level (bytes: Vec<u8>) -> Level {
581 let mut level: Level = Level::new();
582 level.blocks = Some(bytes);
583 return level;
584}
585
586pub fn level_to_pre_classic (level: Level, path: String) -> Result<(), ClassicError> {
591 let name: &str = if path == "" {"level.dat"} else {"/level.dat"};
592
593 let mut tiles: Vec<u8> = level.blocks.unwrap();
594 while tiles.len() > 256 * 64 * 256 {tiles.pop();}
596
597 let output= OpenOptions::new()
598 .write(true)
599 .create(true)
600 .open(path + name)
601 .unwrap();
602
603 let mut encoder = GzEncoder::new(output, Compression::default());
604 encoder.write_all(&tiles).unwrap();
605
606 Ok(())
607}
608
609pub fn classic_13_to_level (bytes: Vec<u8>) -> Level {
615 let mut buf: usize = 4;
616 let mut level: Level = Level::new();
617
618 level.version = Some(bytes[buf]);
620 buf += 1;
621
622 let mut sh: u16 = u16_fs(buf, &bytes[..]);
624 buf += 2;
625 level.name = Some(str_fs(buf, &bytes[..], sh as i32));
626 buf += sh as usize;
627
628 sh = u16_fs(buf, &bytes[..]);
630 buf += 2;
631 level.creator = Some(str_fs(buf, &bytes[..], sh as i32));
632 buf += sh as usize;
633
634 level.createTime = Some(i64_fs(buf, &bytes[..]));
636 buf += 8;
637
638 level.width = Some(i16_fs(buf, &bytes[..]) as i32);
640 buf += 2;
641 level.height = Some(i16_fs(buf, &bytes[..]) as i32);
642 buf += 2;
643 level.depth = Some(i16_fs(buf, &bytes[..]) as i32);
644 buf += 2;
645
646 let mut tile_map: Vec<u8> = Vec::new();
648 for i in buf..bytes.len() as usize {
649 tile_map.push(bytes[i as usize]);
650 }
651
652 level.blocks = Some(tile_map);
653
654 return level;
655
656}
657
658pub fn level_to_classic_13(level: Level, path: String) -> Result<(),ClassicError> {
662 let mut bytes: Vec<u8> = Vec::new();
663
664 let magic_number: u32 = 0x271BB788;
666 bytes.extend_from_slice(&magic_number.to_be_bytes());
667 if level.version.is_some() {bytes.push(level.version.unwrap())} else {bytes.push(1)}
668
669 let name = if level.name.is_some() {level.name.unwrap()} else {String::from("A Nice World")};
671 let len = name.len() as u16;
672 bytes.extend_from_slice(&len.to_be_bytes());
673 bytes.extend_from_slice(name.as_bytes());
674 let creator = if level.creator.is_some() {level.creator.unwrap()} else {String::from("noname")};
679 let len = creator.len() as u16;
680 bytes.extend_from_slice(&len.to_be_bytes());
681 bytes.extend_from_slice(creator.as_bytes());
682 if level.createTime.is_some() {
687 bytes.extend_from_slice(&level.createTime.unwrap().to_be_bytes())
688 } else {
689 bytes.extend_from_slice(&(0 as i64).to_be_bytes())
690 }
691
692 if level.width.is_some() {
694 bytes.extend_from_slice(&(level.width.unwrap() as i16).to_be_bytes())
695 } else {
696 bytes.extend_from_slice(&(256 as i16).to_be_bytes())
697 }
698 if level.height.is_some() {
699 bytes.extend_from_slice(&(level.height.unwrap() as i16).to_be_bytes())
700 } else {
701 bytes.extend_from_slice(&(256 as i16).to_be_bytes())
702 }
703 if level.depth.is_some() {
704 bytes.extend_from_slice(&(level.depth.unwrap() as i16).to_be_bytes())
705 } else {
706 bytes.extend_from_slice(&(64 as i16).to_be_bytes())
707 }
708
709 if level.blocks.is_some() {
711 for tile in level.blocks.unwrap() {bytes.push(tile)}
712 }
713
714 let output= OpenOptions::new()
716 .write(true)
717 .create(true)
718 .open(path)
719 .unwrap();
720
721 let mut encoder = GzEncoder::new(output, Compression::default());
723 encoder.write_all(&bytes).unwrap();
724
725 Ok(())
726}
727
728pub fn classic_to_level (bytes: Vec<u8>) -> Result<Level, ClassicError> {
734
735 let mut buf: usize = 4;
737 let mut level: Level = Level::new();
738
739 level.version = Some(bytes[buf as usize]);
740 buf += 1;
741
742 let mut deserializer: Deserializer = Deserializer::new();
744 let contents: Vec<serialize::Object> = deserializer.deserialize(&bytes[buf..])?;
745
746 if contents.len() != 1 { return Err(ClassicError::DeserializeError(DeserializeError::InvalidContentLength(1, contents.len()))) }
748
749 let object: serialize::NewObject = contents[0].get_new_object()?;
750
751 let class_info: serialize::NewClassDesc = object.class_desc.get_new_class_desc()?;
753 let class_data: serialize::ClassData = object.class_data.unwrap();
754
755 if class_info.class_name != "com.mojang.minecraft.level.Level" {
756 return Err(ClassicError::InvalidClass(class_info.class_name.clone()))
757 }
758
759 let fields: serialize::Fields = class_info.class_desc_info.unwrap().fields;
760 let values: Vec<serialize::Value> = class_data.values;
761
762 for i in 0..fields.count as usize {
764 match fields.field_descs[i].get_field_name()?.as_str() {
765 "createTime" => { level.createTime = Some(values[i].get_long()?) },
766 "depth" => { level.depth = Some(values[i].get_integer()?) },
767 "height" => { level.height = Some(values[i].get_integer()?) },
768 "rotSpawn" => { level.rotSpawn = Some(values[i].get_float()?) },
769 "tickCount" => { level.tickCount = Some(values[i].get_integer()?) },
770 "unprocessed" => { level.unprocessed = Some(values[i].get_integer()?) },
771 "width" => { level.width = Some(values[i].get_integer()?) },
772 "xSpawn" => { level.xSpawn = Some(values[i].get_integer()?) },
773 "ySpawn" => { level.zSpawn = Some(values[i].get_integer()?) },
774 "zSpawn" => { level.ySpawn = Some(values[i].get_integer()?) },
775 "networkMode" => { level.networkMode = Some(values[i].get_boolean()?) },
776 "cloudColor" => { level.cloudColor = Some(values[i].get_integer()?) },
777 "fogColor" => { level.fogColor = Some(values[i].get_integer()?) },
778 "skyColor" => { level.skyColor = Some(values[i].get_integer()?) },
779 "waterLevel" => { level.waterLevel = Some(values[i].get_integer()?) },
780 "creativeMode" => { level.creativeMode = Some(values[i].get_boolean()?) },
781 "growTrees" => { level.growTrees = Some(values[i].get_boolean()?) },
782 "blocks" => {
783 let wrapped: Vec<serialize::Value> = values[i].get_array()?;
784 let mut blocks: Vec<u8> = Vec::new();
785 for value in wrapped {
786 blocks.push(value.get_byte()?)
787 }
788 level.blocks = Some(blocks);
789 },
790 "creator" => {
791 level.creator = values[i].get_object()?.get_new_string()?.string;
792 },
793 "name" => {
794 level.name = values[i].get_object()?.get_new_string()?.string;
795 },
796 "entities" => (), "blockMap" => {
798
799 let block_map: serialize::NewObject = values[i].get_object()?.get_new_object()?;
801 let field_descs: Vec<serialize::FieldDesc> = block_map.class_desc.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs;
802 let values1: Vec<serialize::Value> = block_map.class_data.unwrap().values;
803
804 let mut entity_grid: Vec<serialize::Value> = Vec::new();
806 for i in 0..field_descs.len() {
807 if field_descs[i].get_field_name()? == "all" {
808 entity_grid = values1[i].clone().get_object()?.get_new_object()?.class_data.unwrap().values[1].get_array()?;
809 }
810 }
811
812 let mut entities: Vec<Entity> = Vec::new();
814 for entity in entity_grid {
815 match parse_entity(entity.get_object()?.get_new_object()?) {
816 Ok(val) => {
817 entities.push(val.clone());
818 if matches!(val.clone(), Entity::Player(_)) {
819 level.player = Some(val.get_player()?);
820 }
821 },
822 Err(e) => println!("Entity Parsing Failed: {e}")
823 }
824 }
825 level.entities = Some(entities);
826 },
827 "player" => {
828 if level.player.is_none() {
831 match parse_entity(values[i].get_object()?.get_new_object()?) {
832 Ok (val) => level.player = Some(val.get_player()?),
833 Err(e) => println!("Player Parsing Failed: {e}")
834 }
835 }
836 },
837 _ => println!("Unexpected Field: {}", fields.field_descs[i].get_field_name()?.as_str())
838
839 }
840 }
841
842 Ok(level)
843}
844
845fn parse_entity (entity: serialize::NewObject) -> Result<Entity,ClassicError> {
846 let name: String = entity.class_desc.get_new_class_desc()?.class_name;
847 let classes: Vec<&str> = name.split(".").collect();
848 let values: Vec<serialize::Value> = entity.class_data.unwrap().values;
849 let mut field_descs: Vec<Vec<serialize::FieldDesc>> = Vec::new();
850 field_descs.push(entity.class_desc.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs);
851 let mut super_class: Box<serialize::ClassDesc> = entity.class_desc.get_new_class_desc()?.class_desc_info.unwrap().super_class_desc;
852 while !matches!(*super_class, serialize::ClassDesc::Null) {
853 field_descs.push(super_class.get_new_class_desc()?.class_desc_info.unwrap().fields.field_descs);
854 super_class = super_class.get_new_class_desc()?.class_desc_info.unwrap().super_class_desc;
855 }
856 let mut entity_fields: EntityFields = EntityFields::new();
857 let mut index: usize = 0;
858 for field in field_descs[field_descs.len()-1].clone() {
859 match field.get_field_name()?.as_str() {
860 "bbHeight" => entity_fields.bbHeight = Some(values[index].get_float()?),
861 "bbWidth" => entity_fields.bbWidth = Some(values[index].get_float()?),
862 "collision" => entity_fields.collision = Some(values[index].get_boolean()?),
863 "fallDistance" => entity_fields.fallDistance = Some(values[index].get_float()?),
864 "footSize" => entity_fields.footSize = Some(values[index].get_float()?),
865 "heightOffset" => entity_fields.heightOffset = Some(values[index].get_float()?),
866 "horizontalCollision" => entity_fields.horizontalCollision = Some(values[index].get_boolean()?),
867 "hovered" => entity_fields.hovered = Some(values[index].get_boolean()?),
868 "makeStepSound" => entity_fields.makeStepSound = Some(values[index].get_boolean()?),
869 "nextStep" => entity_fields.nextStep = Some(values[index].get_integer()?),
870 "noPhysics" => entity_fields.noPhysics = Some(values[index].get_boolean()?),
871 "onGround" => entity_fields.onGround = Some(values[index].get_boolean()?),
872 "pushthrough" => entity_fields.pushthrough = Some(values[index].get_float()?),
873 "removed" => entity_fields.removed = Some(values[index].get_boolean()?),
874 "slide" => entity_fields.slide = Some(values[index].get_boolean()?),
875 "textureId" => entity_fields.textureId = Some(values[index].get_integer()?),
876 "walkDist" => entity_fields.walkDist = Some(values[index].get_float()?),
877 "walkDistO" => entity_fields.walkDistO = Some(values[index].get_float()?),
878 "x" => entity_fields.x = Some(values[index].get_float()?),
879 "xOld" => entity_fields.xOld = Some(values[index].get_float()?),
880 "xRot" => entity_fields.xRot = Some(values[index].get_float()?),
881 "xRotO" => entity_fields.xRotO = Some(values[index].get_float()?),
882 "xd" => entity_fields.xd = Some(values[index].get_float()?),
883 "xo" => entity_fields.xo = Some(values[index].get_float()?),
884 "y" => entity_fields.y = Some(values[index].get_float()?),
885 "yOld" => entity_fields.yOld = Some(values[index].get_float()?),
886 "yRot" => entity_fields.yRot = Some(values[index].get_float()?),
887 "yRotO" => entity_fields.yRotO = Some(values[index].get_float()?),
888 "ySlideOffset" => entity_fields.ySlideOffset = Some(values[index].get_float()?),
889 "yd" => entity_fields.yd = Some(values[index].get_float()?),
890 "yo" => entity_fields.yo = Some(values[index].get_float()?),
891 "z" => entity_fields.z = Some(values[index].get_float()?),
892 "zOld" => entity_fields.zOld = Some(values[index].get_float()?),
893 "zd" => entity_fields.zd = Some(values[index].get_float()?),
894 "zo" => entity_fields.zo = Some(values[index].get_float()?),
895 "bb" => {
896 let aabb_vals: Vec<serialize::Value> = values[index].get_object()?.get_new_object()?.class_data.unwrap().values;
897 let aabb: AABB = AABB {
898 epsilon: aabb_vals[0].get_float()?,
899 x0: aabb_vals[1].get_float()?,
900 x1: aabb_vals[2].get_float()?,
901 y0: aabb_vals[3].get_float()?,
902 y1: aabb_vals[4].get_float()?,
903 z0: aabb_vals[5].get_float()?,
904 z1: aabb_vals[6].get_float()?
905 };
906 entity_fields.bb = Some(aabb);
907 },
908 "blockMap" => (),
909 "level" => (),
910 _ => println!("Unexpected entity field found: {}", field.get_field_name()?.as_str())
911 }
912 index += 1;
913 }
914 if classes[3] == "mob" || classes[3] == "player" {
915 let mut mob: Mob = Mob::new();
916 mob.entity = Some(entity_fields);
917 for field in field_descs[field_descs.len()-2].clone() {
918 match field.get_field_name()?.as_str() {
919 "airSupply" => mob.airSupply = Some(values[index].get_integer()?),
920 "allowAlpha" => mob.allowAlpha = Some(values[index].get_boolean()?),
921 "animStep" => mob.animStep = Some(values[index].get_float()?),
922 "animStepO" => mob.animStepO = Some(values[index].get_float()?),
923 "attackTime" => mob.attackTime = Some(values[index].get_integer()?),
924 "bobStrength" => mob.bobStrength = Some(values[index].get_float()?),
925 "dead" => mob.dead = Some(values[index].get_boolean()?),
926 "deathScore" => mob.deathScore = Some(values[index].get_integer()?),
927 "deathTime" => mob.deathTime = Some(values[index].get_integer()?),
928 "hasHair" => mob.hasHair = Some(values[index].get_boolean()?),
929 "health" => mob.health = Some(values[index].get_integer()?),
930 "hurtDir" => mob.hurtDir = Some(values[index].get_float()?),
931 "hurtDuration" => mob.hurtDuration = Some(values[index].get_integer()?),
932 "hurtTime" => mob.hurtTime = Some(values[index].get_integer()?),
933 "invulnerableDuration" => mob.invulnerableDuration = Some(values[index].get_integer()?),
934 "invulnerableTime" => mob.invulnerableTime = Some(values[index].get_integer()?),
935 "lastHealth" => mob.lastHealth = Some(values[index].get_integer()?),
936 "oRun" => mob.oRun = Some(values[index].get_float()?),
937 "oTilt" => mob.oTilt = Some(values[index].get_float()?),
938 "renderOffset" => mob.renderOffset = Some(values[index].get_float()?),
939 "rot" => mob.rot = Some(values[index].get_float()?),
940 "rotA" => mob.rotA = Some(values[index].get_float()?),
941 "rotOffs" => mob.rotOffs = Some(values[index].get_float()?),
942 "run" => mob.run = Some(values[index].get_float()?),
943 "speed" => mob.speed = Some(values[index].get_float()?),
944 "tickCount" => mob.tickCount = Some(values[index].get_integer()?),
945 "tilt" => mob.tilt = Some(values[index].get_float()?),
946 "timeOffs" => mob.timeOffs = Some(values[index].get_float()?),
947 "yBodyRot" => mob.yBodyRot = Some(values[index].get_float()?),
948 "yBodyRotO" => mob.yBodyRotO = Some(values[index].get_float()?),
949 "ai" => {
950 let ai_vals: Vec<serialize::Value> = values[index].get_object()?.get_new_object()?.class_data.unwrap().values;
951 let random_vals: Vec<serialize::Value> = ai_vals[11].get_object()?.get_new_object()?.class_data.unwrap().values;
952 let random: Random1 = Random1 {
953 haveNextNextGaussian: random_vals[0].get_boolean()?,
954 nextNextGaussian: random_vals[1].get_double()?,
955 seed: random_vals[2].get_long()?
956 };
957 let att_tar: Option<Entity> = match ai_vals[8].get_object()? {
958 serialize::Object::NewObject(_) => match parse_entity(ai_vals[8].get_object()?.get_new_object()?) {
959 Ok (val) => Some(val),
960 Err(e) => {
961 println!("Error Handling Target of {name}: {e}");
962 None
963 }
964 },
965 _ => None
966 };
967 let ai: AI = AI {
968 damage: ai_vals[0].get_integer()?,
969 attackDelay: ai_vals[1].get_integer()?,
970 jumping: ai_vals[2].get_boolean()?,
971 noActionTime: ai_vals[3].get_integer()?,
972 runSpeed: ai_vals[4].get_float()?,
973 xxa: ai_vals[5].get_float()?,
974 yRotA: ai_vals[6].get_float()?,
975 yya: ai_vals[7].get_float()?,
976 attackTarget: Box::new(att_tar),
977 mob: name.clone(),
978 random: random
979 };
980 mob.ai = Some(ai);
981 },
982 "modelName" => mob.modelName = Some(values[index].get_object()?.get_new_string()?.string.unwrap()),
983 "textureName" => mob.textureName = Some(values[index].get_object()?.get_new_string()?.string.unwrap()),
984 _ => println!("Unexpected mob field found: {}", field.get_field_name()?.as_str())
985 }
986 index += 1;
987 }
988 match classes[4] {
989 "Sheep" => {
990 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
991 let sheep: Sheep = Sheep {
992 graze: values[index].get_float()?,
993 grazeO: values[index + 1].get_float()?,
994 grazing: values[index + 2].get_boolean()?,
995 grazingTime: values[index + 3].get_integer()?,
996 hasFur: values[index + 4].get_boolean()?,
997 quadrapedMob: quadraped_mob
998 };
999 return Ok(Entity::Sheep(sheep))
1000 },
1001 "Pig" => {
1002 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
1003 let pig: Pig = Pig { quadrapedMob: quadraped_mob };
1004 return Ok(Entity::Pig(pig))
1005 },
1006 "Creeper" => {
1007 let creeper: Creeper = Creeper { mob: mob };
1008 return Ok(Entity::Creeper(creeper))
1009 },
1010 "Zombie" => {
1011 let humanoid_mob: HumanoidMob = HumanoidMob {
1012 armor: values[index].get_boolean()?,
1013 helmet: values[index + 1].get_boolean()?,
1014 mob: mob
1015 };
1016 let zombie: Zombie = Zombie { humanoidMob: humanoid_mob };
1017 return Ok(Entity::Zombie(zombie))
1018 },
1019 "Skeleton" => {
1020 let humanoid_mob: HumanoidMob = HumanoidMob {
1021 armor: values[index].get_boolean()?,
1022 helmet: values[index + 1].get_boolean()?,
1023 mob: mob
1024 };
1025 let zombie: Zombie = Zombie { humanoidMob: humanoid_mob };
1026 let skeleton: Skeleton = Skeleton { zombie: zombie };
1027 return Ok(Entity::Skeleton(skeleton))
1028 },
1029 "Spider" => {
1030 let quadraped_mob: QuadrapedMob = QuadrapedMob { mob: mob };
1031 let spider: Spider = Spider { quadrapedMob: quadraped_mob };
1032 return Ok (Entity::Spider(spider))
1033 },
1034 "Player" => {
1035 let inv_vals: Vec<serialize::Value> = values[index + 5].get_object()?.get_new_object()?.class_data.unwrap().values;
1036 let mut arrs: Vec<Vec<i32>> = Vec::new();
1037 for i in 1..inv_vals.len() {
1038 let mut arr: Vec<i32> = Vec::new();
1039 for val in inv_vals[i].get_array()? {
1040 arr.push(val.get_integer()?);
1041 }
1042 arrs.push(arr);
1043 }
1044 let inventory: Inventory = Inventory {
1045 selected: inv_vals[0].get_integer()?,
1046 count: arrs[0].clone(),
1047 popTime: arrs[1].clone(),
1048 slots: arrs[2].clone(),
1049 };
1050 let player: Player = Player {
1051 arrows: values[index].get_integer()?,
1052 bob: values[index + 1].get_float()?,
1053 oBob: values[index + 2].get_float()?,
1054 score: values[index + 3].get_integer()?,
1055 userType: values[index + 4].get_byte()?,
1056 inventory: inventory,
1057 mob: mob
1058 };
1059 return Ok(Entity::Player(player.clone()))
1060 },
1061 _ => return Err(ClassicError::UnexpectedEntity(name))
1062 }
1063 } else {
1064 match classes[4] {
1065 "Arrow" => {
1066 let owner: Option<Entity> = match values[index + 13].get_object()? {
1067 serialize::Object::NewObject(_) => match parse_entity(values[index + 13].get_object()?.get_new_object()?) {
1068 Ok (val) => Some(val),
1069 Err(e) => {
1070 println!("Error Handling Target of {name}: {e}");
1071 None
1072 }
1073 },
1074 _ => None
1075 };
1076 let arrow: Arrow = Arrow {
1077 damage: values[index].get_integer()?,
1078 gravity: values[index + 1].get_float()?,
1079 hasHilt: values[index + 2].get_boolean()?,
1080 stickTime: values[index + 3].get_integer()?,
1081 time: values[index + 4].get_integer()?,
1082 atype: values[index + 5].get_integer()?,
1083 xRot: values[index + 6].get_float()?,
1084 xRotO: values[index + 7].get_float()?,
1085 xd: values[index + 8].get_float()?,
1086 yRot: values[index + 9].get_float()?,
1087 yRotO: values[index + 10].get_float()?,
1088 yd: values[index + 11].get_float()?,
1089 zd: values[index + 12].get_float()?,
1090 owner: Box::new(owner),
1091 entity: entity_fields
1092 };
1093 return Ok(Entity::Arrow(arrow))
1094 },
1095 "Item" => {
1096 let item: Item = Item {
1097 age: values[index].get_integer()?,
1098 resource: values[index + 1].get_integer()?,
1099 rot: values[index + 2].get_float()?,
1100 tickCount: values[index + 3].get_integer()?,
1101 xd: values[index + 4].get_float()?,
1102 yd: values[index + 5].get_float()?,
1103 zd: values[index + 6].get_float()?,
1104 entity: entity_fields
1105 };
1106 return Ok(Entity::Item(item));
1107 },
1108 "PrimedTnt" => {
1109 let primed_tnt: PrimedTnt = PrimedTnt {
1110 life: values[index].get_integer()?,
1111 xd: values[index + 1].get_float()?,
1112 yd: values[index + 2].get_float()?,
1113 zd: values[index + 3].get_float()?,
1114 entity: entity_fields
1115 };
1116 return Ok(Entity::PrimedTnt(primed_tnt))
1117 },
1118 "Sign" => {
1119 let mut arr: Vec<String> = Vec::new();
1120 for str in values[index + 4].get_array()? {
1121 arr.push(str.get_object()?.get_new_string()?.string.unwrap())
1122 }
1123 let sign: Sign = Sign {
1124 rot: values[index].get_float()?,
1125 xd: values[index + 1].get_float()?,
1126 yd: values[index + 2].get_float()?,
1127 zd: values[index + 3].get_float()?,
1128 messages: arr,
1129 entity: entity_fields
1130 };
1131 return Ok(Entity::Sign(sign))
1132 }
1133 "fx" => {
1134 let smolder: Smolder = Smolder {
1135 life: values[index].get_integer()?,
1136 lifeTime: values[index + 1].get_integer()?,
1137 entity: entity_fields
1138 };
1139 return Ok(Entity::Smolder(smolder))
1140 },
1141 _ => return Err(ClassicError::UnexpectedEntity(name))
1142 }
1143 }
1144}