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