diff --git a/.gitignore b/.gitignore index 630ca0c..c7c700a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ data/pub/*.edf data/pub/*.enf data/pub/*.evf data/pub/*.etf +data/pub/*.epf data/pub/**/*.json data/maps/*.emf data/quests/*.txt* diff --git a/docker-compose.yml b/docker-compose.yml index 9a3f5e1..0500007 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: db: - image: mysql + image: mysql:8.0 command: --default-authentication-plugin=mysql_native_password restart: always environment: @@ -13,4 +13,4 @@ services: ports: - "3306:3306" volumes: - - ./db-init/:/docker-entrypoint-initdb.d/ \ No newline at end of file + - ./db-init/:/docker-entrypoint-initdb.d/ diff --git a/src/utils/load_class_file.rs b/src/utils/load_class_file.rs index 4362c3b..61fb14d 100644 --- a/src/utils/load_class_file.rs +++ b/src/utils/load_class_file.rs @@ -76,11 +76,14 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dat001.ecf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/dat001.ecf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(Ecf::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(Ecf::deserialize(&reader)?); + } + + Ok(Ecf::default()) } diff --git a/src/utils/load_drop_file.rs b/src/utils/load_drop_file.rs index b6fc7b6..96b9461 100644 --- a/src/utils/load_drop_file.rs +++ b/src/utils/load_drop_file.rs @@ -56,11 +56,61 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dtd001.edf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/serv_drops.epf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(DropFile::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + + if reader.get_fixed_string(3) != "EDF" { + return Err("Invalid file".into()); + } + + reader.get_short(); + reader.get_short(); + + let mut edf = DropFile::default(); + + let num_records = reader.get_short(); + + edf.npcs = Vec::with_capacity(num_records as usize); + + reader.get_char(); + + for _ in 0..num_records { + let mut record = DropNpcRecord::default(); + record.npc_id = reader.get_short(); + let num_drops = reader.get_short(); + + record.drops = Vec::with_capacity(num_drops as usize); + for _ in 0..num_drops { + let item_id = reader.get_short(); + let min_amount = reader.get_three(); + let max_amount = reader.get_three(); + let rate = ((reader.get_short() as f32) / 10_000. * 64_000.).floor() as i32; + record.drops.push(DropRecord { + item_id, + min_amount, + max_amount, + rate, + }); + } + + edf.npcs.push(record); + } + + return Ok(edf); + } + + if let Ok(mut file) = File::open("data/pub/dtd001.edf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(DropFile::deserialize(&reader)?); + } + + Ok(DropFile::default()) } diff --git a/src/utils/load_inn_file.rs b/src/utils/load_inn_file.rs index 076ada0..baba0ac 100644 --- a/src/utils/load_inn_file.rs +++ b/src/utils/load_inn_file.rs @@ -1,4 +1,4 @@ -use std::{fs::File, io::Read}; +use std::{cmp, fs::File, io::Read}; use bytes::Bytes; use eolib::{ @@ -81,11 +81,69 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/din001.eid")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/serv_inns.epf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(InnFile::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + if reader.get_fixed_string(3) != "EID" { + return Err("Invalid file".into()); + } + + reader.get_short(); + reader.get_short(); + + let mut eif = InnFile::default(); + + let num_records = reader.get_short(); + + eif.inns = Vec::with_capacity(num_records as usize); + + reader.get_char(); + + for _ in 0..num_records { + let mut record = InnRecord::default(); + record.behavior_id = reader.get_short(); + let name_length = reader.get_char(); + record.name = reader.get_fixed_string(name_length as usize); + + // sleep cost + reader.get_three(); + + record.sleep_map = reader.get_short(); + record.sleep_x = reader.get_char(); + record.sleep_y = reader.get_char(); + record.spawn_map = reader.get_short(); + record.spawn_x = reader.get_char(); + record.spawn_y = reader.get_char(); + record.alternate_spawn_enabled = reader.get_short() != 0; + record.alternate_spawn_map = reader.get_short(); + record.alternate_spawn_x = reader.get_char(); + record.alternate_spawn_y = reader.get_char(); + + let num_questions = reader.get_char(); + for i in 0..cmp::min(num_questions as usize, 3) { + let question_length = reader.get_char(); + let question = reader.get_fixed_string(question_length as usize); + let answer_length = reader.get_char(); + let answer = reader.get_fixed_string(answer_length as usize); + record.questions[i] = InnQuestionRecord { question, answer }; + } + eif.inns.push(record); + } + + return Ok(eif); + } + + if let Ok(mut file) = File::open("data/pub/din001.eid") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(InnFile::deserialize(&reader)?); + } + + Ok(InnFile::default()) } diff --git a/src/utils/load_item_file.rs b/src/utils/load_item_file.rs index bb766ca..34cda8b 100644 --- a/src/utils/load_item_file.rs +++ b/src/utils/load_item_file.rs @@ -108,11 +108,14 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dat001.eif")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/dat001.eif") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(Eif::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(Eif::deserialize(&reader)?); + } + + Ok(Eif::default()) } diff --git a/src/utils/load_npc_file.rs b/src/utils/load_npc_file.rs index bf7f58f..6b76e10 100644 --- a/src/utils/load_npc_file.rs +++ b/src/utils/load_npc_file.rs @@ -88,11 +88,14 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dtn001.enf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/dtn001.enf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(Enf::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(Enf::deserialize(&reader)?); + } + + Ok(Enf::default()) } diff --git a/src/utils/load_shop_file.rs b/src/utils/load_shop_file.rs index 2eb7db1..d8278e2 100644 --- a/src/utils/load_shop_file.rs +++ b/src/utils/load_shop_file.rs @@ -85,11 +85,91 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dts001.esf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/serv_shops.epf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(ShopFile::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + + if reader.get_fixed_string(3) != "ESF" { + return Err("Invalid file".into()); + } + + reader.get_short(); + reader.get_short(); + + let mut esf = ShopFile::default(); + + let num_records = reader.get_short(); + + esf.shops = Vec::with_capacity(num_records as usize); + + reader.get_char(); + + for _ in 0..num_records { + let mut record = ShopRecord::default(); + record.behavior_id = reader.get_short(); + + let name_length = reader.get_char(); + record.name = reader.get_fixed_string(name_length as usize); + record.min_level = reader.get_short(); + record.max_level = reader.get_short(); + record.class_requirement = reader.get_char(); + + let num_trades = reader.get_short(); + let num_crafts = reader.get_char(); + + record.trades = Vec::with_capacity(num_trades as usize); + record.crafts = Vec::with_capacity(num_crafts as usize); + + for _ in 0..num_trades { + record.trades.push(ShopTradeRecord { + item_id: reader.get_short(), + buy_price: reader.get_three(), + sell_price: reader.get_three(), + max_amount: reader.get_char(), + }); + } + + for _ in 0..num_crafts { + record.crafts.push(ShopCraftRecord { + item_id: reader.get_short(), + ingredients: [ + ShopCraftIngredientRecord { + item_id: reader.get_short(), + amount: reader.get_char(), + }, + ShopCraftIngredientRecord { + item_id: reader.get_short(), + amount: reader.get_char(), + }, + ShopCraftIngredientRecord { + item_id: reader.get_short(), + amount: reader.get_char(), + }, + ShopCraftIngredientRecord { + item_id: reader.get_short(), + amount: reader.get_char(), + }, + ], + }); + } + + esf.shops.push(record); + } + + return Ok(esf); + } + + if let Ok(mut file) = File::open("data/pub/dts001.esf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(ShopFile::deserialize(&reader)?); + } + + Ok(ShopFile::default()) } diff --git a/src/utils/load_skill_master_file.rs b/src/utils/load_skill_master_file.rs index bf0290d..6e2a4ac 100644 --- a/src/utils/load_skill_master_file.rs +++ b/src/utils/load_skill_master_file.rs @@ -77,11 +77,76 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dsm001.emf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/serv_trainers.epf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(SkillMasterFile::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + + if reader.get_fixed_string(3) != "ETF" { + return Err("Invalid file".into()); + } + + reader.get_short(); + reader.get_short(); + + let mut emf = SkillMasterFile::default(); + + let num_records = reader.get_short(); + + emf.skill_masters = Vec::with_capacity(num_records as usize); + + reader.get_char(); + + for _ in 0..num_records { + let mut record = SkillMasterRecord::default(); + record.behavior_id = reader.get_short(); + let name_length = reader.get_char(); + record.name = reader.get_fixed_string(name_length as usize); + + record.min_level = reader.get_short(); + record.max_level = reader.get_short(); + record.class_requirement = reader.get_char(); + + let num_skills = reader.get_short(); + record.skills = Vec::with_capacity(num_skills as usize); + + for _ in 0..num_skills { + record.skills.push(SkillMasterSkillRecord { + skill_id: reader.get_short(), + level_requirement: reader.get_short(), + class_requirement: reader.get_char(), + price: reader.get_three(), + skill_requirements: [ + reader.get_short(), + reader.get_short(), + reader.get_short(), + reader.get_short(), + ], + str_requirement: reader.get_short(), + int_requirement: reader.get_short(), + wis_requirement: reader.get_short(), + agi_requirement: reader.get_short(), + con_requirement: reader.get_short(), + cha_requirement: reader.get_short(), + }); + } + + emf.skill_masters.push(record); + } + + return Ok(emf); + } + + if let Ok(mut file) = File::open("data/pub/dsm001.emf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(SkillMasterFile::deserialize(&reader)?); + } + + Ok(SkillMasterFile::default()) } diff --git a/src/utils/load_spell_file.rs b/src/utils/load_spell_file.rs index 851e97d..d675775 100644 --- a/src/utils/load_spell_file.rs +++ b/src/utils/load_spell_file.rs @@ -102,11 +102,14 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { - let mut file = File::open("data/pub/dsl001.esf")?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; + if let Ok(mut file) = File::open("data/pub/dsl001.esf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; - let bytes = Bytes::from(buf); - let reader = EoReader::new(bytes); - Ok(Esf::deserialize(&reader)?) + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + return Ok(Esf::deserialize(&reader)?); + } + + Ok(Esf::default()) } diff --git a/src/utils/load_talk_file.rs b/src/utils/load_talk_file.rs index 806a858..e549779 100644 --- a/src/utils/load_talk_file.rs +++ b/src/utils/load_talk_file.rs @@ -55,6 +55,49 @@ fn load_json() -> Result> { } fn load_pub() -> Result> { + if let Ok(mut file) = File::open("data/pub/serv_chats.epf") { + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + + let bytes = Bytes::from(buf); + let reader = EoReader::new(bytes); + + if reader.get_fixed_string(3) != "ETF" { + return Err("Invalid file".into()); + } + + reader.get_short(); + reader.get_short(); + + let mut etf = TalkFile::default(); + + let num_records = reader.get_short(); + + etf.npcs = Vec::with_capacity(num_records as usize); + + reader.get_char(); + + for _ in 0..num_records { + let mut record = TalkRecord::default(); + record.npc_id = reader.get_short(); + reader.get_char(); + record.rate = reader.get_char(); + + let num_messages = reader.get_char(); + record.messages = Vec::with_capacity(num_messages as usize); + for _ in 0..num_messages { + let length = reader.get_char(); + record.messages.push(TalkMessageRecord { + message: reader.get_fixed_string(length as usize), + }); + } + + etf.npcs.push(record); + } + + return Ok(etf); + } + let mut file = File::open("data/pub/ttd001.etf")?; let mut buf = Vec::new(); file.read_to_end(&mut buf)?;