Skip to main content

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};
16use std::path::PathBuf;
17
18use thiserror::Error;
19
20#[derive(Default,Clone)]
21pub struct Level {
22    pub blocks: Option<Vec<u8>>, //pc-132211
23    pub version: Option<u8>, //0.0.13a-dev
24    pub name: Option<String>, //0.0.13a-dev
25    pub creator: Option<String>, //0.0.13a-dev
26    pub createTime: Option<i64>, //0.0.13a-dev
27    pub width: Option<i32>, //0.0.13a-dev
28    pub height: Option<i32>, //0.0.13a-dev
29    pub depth: Option<i32>, //0.0.13a-dev
30    pub xSpawn: Option<i32>, //0.0.14a_08
31    pub ySpawn: Option<i32>, //0.0.14a_08
32    pub zSpawn: Option<i32>, //0.0.14a_08
33    pub rotSpawn: Option<f32>, //0.0.14a_08
34    pub tickCount: Option<i32>, //0.0.14a_08
35    pub unprocessed: Option<i32>, //0.0.14a_08
36    pub entities: Option<Vec<Entity>>, //0.0.14a_08 - Removed 0.25_05_st
37    pub networkMode: Option<bool>, //0.0.19a_04
38    pub cloudColor: Option<i32>, //0.0.25_05_st
39    pub fogColor: Option<i32>, //0.0.25_05_st
40    pub skyColor: Option<i32>, //0.0.25_05_st
41    pub waterLevel: Option<i32>, //0.0.25_05_st
42    pub player: Option<Player>, //0.0.25_05_st
43    //blockMap was added and the only thing of use it holds is the entity list
44    //blockMap therefore just gets parsed into entities
45    //Note the player is not included in this list when parsed
46    //blockMap: Option<BlockMap> //0.0.25_05_st
47    pub creativeMode: Option<bool>, //0.0.28_01
48    pub growTrees: Option<bool> //0.0.29
49}
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
530/*
531* The following function accepts a file path, then reads in the file
532* and determines which version the classic file is from
533*/
534pub fn read_level (file: PathBuf) -> Result <Level, ClassicError> {
535    //Reading in a classic level and converting it to a decompressed stream of bytes
536    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    //Checking for a magic number at the start of the file
542    let magic_number: u32 = u32_fs(0, &bytes[..]);
543
544    //Preclassic levels do not have a magic number
545    if magic_number != 0x271BB788 {return Ok(pre_classic_to_level(bytes))}
546
547    //All 13a levels use version 1
548    if bytes[4] == 1 {return Ok(classic_13_to_level(bytes))}
549
550    //All future levels use version 2
551    if bytes[4] == 2 {return Ok(classic_to_level(bytes)?)}
552
553    return Err(ClassicError::LevelNotRecognized())
554
555}
556
557/*
558* This function accepts a level object and a path and writes it to a level.dat
559* in a classic format
560*/
561pub 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            //Serialization is not yet supported
567            return Err(ClassicError::UnsupportedFeature())
568        },
569        _ => return Err(ClassicError::InvalidFileFormat(format))
570    }
571
572    return Ok(())
573}
574
575/*
576* This function will be called to parse all Minecraft Levels from
577* rd-132211 to Classic 12a_03 
578* Pre-classic saves only store an array of blocks in the shape of 256 x 64 x 256
579*/
580pub 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
586/*
587* This function will write a minecraft level in pre-classic format
588* Pre-classic saves only store an array of blocks in the shape of 256 x 64 x 256
589*/
590pub 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    //Removing blocks if the array is greater than the size pre-classic can support
595    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
609/*
610* This function will be called to parse all 13a Classic Minecraft Levels
611* These levels follow a specific format, where the bytes are not labeled
612* or serialized, but rather just follow a standard structure
613*/
614pub fn classic_13_to_level (bytes: Vec<u8>) -> Level {
615    let mut buf: usize = 4;
616    let mut level: Level = Level::new();
617
618    //Setting level version - Byte format
619    level.version = Some(bytes[buf]);
620    buf += 1;
621
622    //Parsing and setting level name - String format
623    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    //Parsing and setting author name - String format
629    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    //Setting timestamp - Long format
635    level.createTime = Some(i64_fs(buf, &bytes[..]));
636    buf += 8;
637
638    //Setting width, depth, and height - Short Format
639    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    //Setting tile map - Array in the format of x -> z -> y
647    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
658/**
659 * Following function writes a level object to a classic file in the 13a file format
660 */
661pub fn level_to_classic_13(level: Level, path: String) -> Result<(),ClassicError> {
662    let mut bytes: Vec<u8> = Vec::new();
663
664    //Writing magic header and version number
665    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    //Setting Author
670    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 chars: Vec<char> = name.chars().collect();
675    //for ch in chars {bytes.push(ch as u8)};
676
677    //Setting World Name
678    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    //let chars: Vec<char> = creator.chars().collect();
683    //for ch in chars {bytes.push(ch as u8)};
684
685    //Setting create time
686    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    //Setting width, height, and depth
693    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    //Adding all blocks
710    if level.blocks.is_some() {
711        for tile in level.blocks.unwrap() {bytes.push(tile)}
712    }
713
714    //Opening file
715    let output= OpenOptions::new()
716        .write(true)
717        .create(true)
718        .open(path)
719        .unwrap();
720
721    //Writing to file
722    let mut encoder = GzEncoder::new(output, Compression::default());
723    encoder.write_all(&bytes).unwrap();
724
725    Ok(())
726}
727
728/*
729* All classic Levels from 14a_08 onwards use Java 6's Object
730* serialization to encode the levels. As such, the following function
731* deserializes the level, and then parse it into a level object
732*/
733pub fn classic_to_level (bytes: Vec<u8>) -> Result<Level, ClassicError> {
734
735    //Moving past the Minecraft specific bytes
736    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    //Deserializing the classic level
743    let mut deserializer: Deserializer = Deserializer::new();
744    let contents: Vec<serialize::Object> = deserializer.deserialize(&bytes[buf..])?;
745
746    //Running checks to determine the deserializer recognized the format of a classic level
747    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    //Unwrapping class info and class data
752    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    //Parsing all fields into a Level object
763    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" => (), //All instances of the entities list are empty in the classic file, and as such this does not need to be parsed 
797            "blockMap" => {
798
799                //Parsing the blockMap into a list of entities and the player
800                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                //Parsing out the "all" list, which is the entity list
805                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                //Iterating through and converting all deserialized entities into Entity objects
813                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                //Checking first if the player has been previously set under entities
829                //Realistically this match arm would only be entered if the entity list corrupted
830                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}