mc_classic/
lib.rs

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