diff --git a/Maple2.File.Generator/XmlArrayGenerator.cs b/Maple2.File.Generator/XmlArrayGenerator.cs index 719a485..0fc2865 100644 --- a/Maple2.File.Generator/XmlArrayGenerator.cs +++ b/Maple2.File.Generator/XmlArrayGenerator.cs @@ -66,7 +66,7 @@ public string _{xmlAttributeName} {{ private void AddSerializer(StringBuilder source, IFieldSymbol field, char delimiter) { string fieldName = $"this.{field.FieldName()}"; - source.Append($"return {fieldName} != null ? string.Join('{delimiter}', {fieldName}) : null;"); + source.Append(@$" return {fieldName} != null ? string.Join('{delimiter}', {fieldName}) : string.Empty;"); } private void AddDeserializer(GeneratorExecutionContext context, StringBuilder source, IFieldSymbol field, char delimiter, bool keepEmpty) { diff --git a/Maple2.File.Parser/Enum/ConditionType.cs b/Maple2.File.Parser/Enum/ConditionType.cs index b529f2d..b971941 100644 --- a/Maple2.File.Parser/Enum/ConditionType.cs +++ b/Maple2.File.Parser/Enum/ConditionType.cs @@ -35,6 +35,7 @@ public enum ConditionType { exp_rate = 43, adventure_level = 44, adventure_level_up = 45, + level_max = 322, // group 8 item_pickup = 2, diff --git a/Maple2.File.Parser/Enum/DungeonType.cs b/Maple2.File.Parser/Enum/DungeonType.cs index 37ce6bf..c98f253 100644 --- a/Maple2.File.Parser/Enum/DungeonType.cs +++ b/Maple2.File.Parser/Enum/DungeonType.cs @@ -39,6 +39,7 @@ public enum DungeonTimerType { public enum DungeonBossRankingType { None = 0, Kill = 1, + kill = Kill, Damage = 2, KillRumble = 3, MultiKill = 4, diff --git a/Maple2.File.Parser/Enum/ItemExchangeScrollType.cs b/Maple2.File.Parser/Enum/ItemExchangeScrollType.cs index ca4562a..87c060e 100644 --- a/Maple2.File.Parser/Enum/ItemExchangeScrollType.cs +++ b/Maple2.File.Parser/Enum/ItemExchangeScrollType.cs @@ -5,4 +5,5 @@ public enum ItemExchangeScrollType { exchange = 1, updated = 2, trading = 3, + upgrade = 4, } diff --git a/Maple2.File.Parser/Enum/NameTagSymbolConditionType.cs b/Maple2.File.Parser/Enum/NameTagSymbolConditionType.cs index 58c571b..77caca3 100644 --- a/Maple2.File.Parser/Enum/NameTagSymbolConditionType.cs +++ b/Maple2.File.Parser/Enum/NameTagSymbolConditionType.cs @@ -13,4 +13,5 @@ public enum NameTagSymbolConditionType { adventure_level, Burning, survivallevel, + return_user, } diff --git a/Maple2.File.Parser/Enum/QuestPropertyType.cs b/Maple2.File.Parser/Enum/QuestPropertyType.cs index 706e3d8..fc6214c 100644 --- a/Maple2.File.Parser/Enum/QuestPropertyType.cs +++ b/Maple2.File.Parser/Enum/QuestPropertyType.cs @@ -4,4 +4,5 @@ public enum QuestPropertyType { special = 0, hidebeginablelist = 1, availablecompletionticket = 2, + hideworldmap = 3, } diff --git a/Maple2.File.Parser/Enum/QuestRewardType.cs b/Maple2.File.Parser/Enum/QuestRewardType.cs index c1ec319..44c4d9e 100644 --- a/Maple2.File.Parser/Enum/QuestRewardType.cs +++ b/Maple2.File.Parser/Enum/QuestRewardType.cs @@ -4,5 +4,6 @@ public enum QuestRewardType { unknown = 0, item = 1, skillPoint = 2, + SkillPoint = skillPoint, statPoint = 3, } diff --git a/Maple2.File.Parser/ItemOptionParser.cs b/Maple2.File.Parser/ItemOptionParser.cs index b05f422..217fd17 100644 --- a/Maple2.File.Parser/ItemOptionParser.cs +++ b/Maple2.File.Parser/ItemOptionParser.cs @@ -20,27 +20,66 @@ public class ItemOptionParser { "mergematerial", "skin", ]; - private readonly string[] randomSuffix = { - "12", "13", "14", "15", "16", "17", "18", "19", - "20", "21", "22", - "30", "31", "32", "33", "34", - "40", "41", - "50", "51", "52", "53", "54", "54_pvp", "55", "56", + private readonly string[] randomSuffix = [ + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "30", + "31", + "32", + "33", + "34", + "40", + "41", + "50", + "51", + "52", + "53", + "54", + "54_pvp", + "55", + "56", "accmanual", "armormanual", "pet_60", "weaponmanual", - }; - private readonly string[] staticSuffix = { - "12", "13", "14", "15", "16", "17", "18", "19", - "20", "21", "22", - "30", "31", "32", "33", "34", - "40", "41", - "50", "51", "52", "53", "54", + ]; + private readonly string[] staticSuffix = [ + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "30", + "31", + "32", + "33", + "34", + "40", + "41", + "50", + "51", + "52", + "53", + "54", "armormanual", "mergematerial", "petequipment", - }; + ]; private readonly string[] variationSuffix = [ "acc", "armor", @@ -50,7 +89,10 @@ public class ItemOptionParser { private readonly M2dReader xmlReader; private readonly XmlSerializer itemOptionConstantSerializer; + private readonly XmlSerializer itemOptionConstantKrSerializer; private readonly XmlSerializer itemOptionSerializer; + private readonly XmlSerializer itemOptionKrSerializer; + private readonly XmlSerializer itemMergeOptionKrSerializer; private readonly XmlSerializer itemMergeOptionSerializer; private readonly XmlSerializer itemOptionPickSerializer; private readonly XmlSerializer itemVariationSerializer; @@ -59,7 +101,10 @@ public class ItemOptionParser { public ItemOptionParser(M2dReader xmlReader) { this.xmlReader = xmlReader; itemOptionConstantSerializer = new XmlSerializer(typeof(ItemOptionConstantRoot)); + itemOptionConstantKrSerializer = new XmlSerializer(typeof(ItemOptionConstantRootKR)); itemOptionSerializer = new XmlSerializer(typeof(ItemOptionRoot)); + itemOptionKrSerializer = new XmlSerializer(typeof(ItemOptionRandomRootKR)); + itemMergeOptionKrSerializer = new XmlSerializer(typeof(ItemMergeOptionRootKR)); itemMergeOptionSerializer = new XmlSerializer(typeof(ItemMergeOptionRoot)); itemOptionPickSerializer = new XmlSerializer(typeof(ItemOptionPickRoot)); itemVariationSerializer = new XmlSerializer(typeof(ItemOptionVariation)); @@ -82,6 +127,20 @@ public IEnumerable ParseConstant() { } } + public IEnumerable ParseConstantKr() { + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/itemoptionconstant.xml"))); + xml = Sanitizer.RemoveUtf8Bom(xml); + var reader = XmlReader.Create(new StringReader(xml)); + var root = itemOptionConstantKrSerializer.Deserialize(reader) as ItemOptionConstantRootKR; + Debug.Assert(root != null); + + foreach (ItemOptionConstant option in root.options) { + if (option.code > 0) { + yield return option; + } + } + } + public IEnumerable ParseRandom() { foreach (string suffix in randomSuffix) { string filename = $"itemoption/option/random/itemoptionrandom_{suffix}.xml"; @@ -98,6 +157,21 @@ public IEnumerable ParseRandom() { } } + public IEnumerable ParseRandomKr() { + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/itemoptionrandom.xml"))); + xml = Sanitizer.RemoveUtf8Bom(xml); + var reader = XmlReader.Create(new StringReader(xml)); + var root = itemOptionKrSerializer.Deserialize(reader) as ItemOptionRandomRootKR; + Debug.Assert(root != null); + + foreach (ItemOptionRandomKR option in root.options) { + if (option.code > 0) { + yield return option; + } + } + + } + public IEnumerable ParseStatic() { foreach (string suffix in staticSuffix) { string filename = $"itemoption/option/static/itemoptionstatic_{suffix}.xml"; @@ -114,6 +188,18 @@ public IEnumerable ParseStatic() { } } + public IEnumerable ParseMergeOptionBaseKr() { + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/itemmergeoptionbase.xml"))); + xml = Sanitizer.RemoveUtf8Bom(xml); + var reader = XmlReader.Create(new StringReader(xml)); + var root = itemMergeOptionKrSerializer.Deserialize(reader) as ItemMergeOptionRootKR; + Debug.Assert(root != null); + + foreach (MergeOptionKR option in root.mergeOption) { + yield return option; + } + } + public IEnumerable ParseMergeOptionBase() { string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/itemmergeoptionbase.xml"))); var reader = XmlReader.Create(new StringReader(xml)); diff --git a/Maple2.File.Parser/ItemParser.cs b/Maple2.File.Parser/ItemParser.cs index bce57b3..28df2ec 100644 --- a/Maple2.File.Parser/ItemParser.cs +++ b/Maple2.File.Parser/ItemParser.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Xml; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.IO.Crypto.Common; using Maple2.File.Parser.Xml.Item; @@ -10,31 +11,45 @@ namespace Maple2.File.Parser; public class ItemParser { private readonly M2dReader xmlReader; - public readonly XmlSerializer NameSerializer; - public readonly XmlSerializer ItemSerializer; + private readonly XmlSerializer nameSerializer; + private readonly XmlSerializer itemSerializer; public ItemParser(M2dReader xmlReader) { this.xmlReader = xmlReader; - NameSerializer = new XmlSerializer(typeof(StringMapping)); - ItemSerializer = new XmlSerializer(typeof(ItemDataRoot)); + nameSerializer = new XmlSerializer(typeof(StringMapping)); + Type type = FeatureLocaleFilter.Locale is "KR" ? typeof(ItemDataKR) : typeof(ItemDataRoot); + itemSerializer = new XmlSerializer(type); + + } + + public IEnumerable<(int Id, string Name, ItemData Data)> Parse() where T : class { + Dictionary itemNames = ItemNames(); + string folderName = "item/"; + if (FeatureLocaleFilter.Locale == "KR") { + folderName = "itemdata/"; + } + foreach (PackFileEntry entry in xmlReader.Files.Where(e => e.Name.StartsWith(folderName))) { + var xml = itemSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as T; + switch (xml) { + case ItemDataRoot root when root.environment != null: + int itemId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); + yield return (itemId, itemNames.GetValueOrDefault(itemId, string.Empty), root.environment); + break; + case ItemDataKR rootKr: + foreach (var dataRoot in rootKr.items) { + if (dataRoot.environment == null) continue; + yield return (dataRoot.id, itemNames.GetValueOrDefault(dataRoot.id, string.Empty), dataRoot.environment); + } + break; + } + } } - public IEnumerable<(int Id, string Name, ItemData Data)> Parse() { + public Dictionary ItemNames() { XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("en/itemname.xml")); - var mapping = NameSerializer.Deserialize(reader) as StringMapping; + var mapping = nameSerializer.Deserialize(reader) as StringMapping; Debug.Assert(mapping != null); - Dictionary itemNames = mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name); - - foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("item/"))) { - var root = ItemSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as ItemDataRoot; - Debug.Assert(root != null); - - ItemData data = root.environment; - if (data == null) continue; - - int itemId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (itemId, itemNames.GetValueOrDefault(itemId), data); - } + return mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name); } } diff --git a/Maple2.File.Parser/MapParser.cs b/Maple2.File.Parser/MapParser.cs index 72045eb..4ffb36f 100644 --- a/Maple2.File.Parser/MapParser.cs +++ b/Maple2.File.Parser/MapParser.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Xml; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.IO.Crypto.Common; using Maple2.File.Parser.Tools; @@ -17,18 +18,33 @@ public class MapParser { public MapParser(M2dReader xmlReader) { this.xmlReader = xmlReader; NameSerializer = new XmlSerializer(typeof(StringMapping)); - MapSerializer = new XmlSerializer(typeof(MapDataRoot)); + Type type = FeatureLocaleFilter.Locale == "KR" ? typeof(MapDataRootKR) : typeof(MapDataRoot); + MapSerializer = new XmlSerializer(type); } public IEnumerable<(int Id, string Name, MapData Data)> Parse() { - XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("en/mapname.xml")); - var mapping = NameSerializer.Deserialize(reader) as StringMapping; - Debug.Assert(mapping != null); + Dictionary mapNames = ParseMapNames(); - Dictionary mapNames = mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name); + IEnumerable entries; + if (FeatureLocaleFilter.Locale == "KR") { + entries = [xmlReader.GetEntry("table/fielddata.xml")]; + } else { + entries = xmlReader.Files.Where(entry => entry.Name.StartsWith("map/")); + } + + foreach (PackFileEntry entry in entries) { + XmlReader reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeMap(xmlReader.GetString(entry)))); + if (FeatureLocaleFilter.Locale == "KR") { + var rootKr = MapSerializer.Deserialize(reader) as MapDataRootKR; + Debug.Assert(rootKr != null); + foreach (MapDataRootKR item in rootKr.fieldData) { + if (item.environment == null) continue; + MapData dataKr = item.environment; + yield return (item.id, mapNames.GetValueOrDefault(item.id, string.Empty), dataKr); + } + continue; + } - foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("map/"))) { - reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeMap(xmlReader.GetString(entry)))); var root = MapSerializer.Deserialize(reader) as MapDataRoot; Debug.Assert(root != null); @@ -36,7 +52,15 @@ public MapParser(M2dReader xmlReader) { if (data == null) continue; int mapId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (mapId, mapNames.GetValueOrDefault(mapId), data); + yield return (mapId, mapNames.GetValueOrDefault(mapId, string.Empty), data); } } + + public Dictionary ParseMapNames() { + var reader = xmlReader.GetXmlReader(xmlReader.GetEntry("en/mapname.xml")); + var mapping = NameSerializer.Deserialize(reader) as StringMapping; + Debug.Assert(mapping != null); + + return mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name); + } } diff --git a/Maple2.File.Parser/NpcParser.cs b/Maple2.File.Parser/NpcParser.cs index a6373d0..b0dbacc 100644 --- a/Maple2.File.Parser/NpcParser.cs +++ b/Maple2.File.Parser/NpcParser.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Xml; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.IO.Crypto.Common; using Maple2.File.Parser.Tools; @@ -11,32 +12,52 @@ namespace Maple2.File.Parser; public class NpcParser { private readonly M2dReader xmlReader; - public readonly XmlSerializer NameSerializer; - public readonly XmlSerializer NpcSerializer; + private readonly XmlSerializer nameSerializer; + private readonly XmlSerializer npcSerializer; + private readonly XmlSerializer npcKrSerializer; public NpcParser(M2dReader xmlReader) { this.xmlReader = xmlReader; - NameSerializer = new XmlSerializer(typeof(StringMapping)); - NpcSerializer = new XmlSerializer(typeof(NpcDataRoot)); + nameSerializer = new XmlSerializer(typeof(StringMapping)); + npcSerializer = new XmlSerializer(typeof(NpcDataRoot)); + npcKrSerializer = new XmlSerializer(typeof(NpcDataListKR)); } - public IEnumerable<(int Id, string Name, NpcData Data, List Dummy)> Parse() { + public Dictionary ParseNpcNames() { XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("en/npcname.xml")); - var mapping = NameSerializer.Deserialize(reader) as StringMapping; - Debug.Assert(mapping != null); - - Dictionary npcNames = mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name); + var npcNames = nameSerializer.Deserialize(reader) as StringMapping; + Debug.Assert(npcNames != null); + return npcNames.key.ToDictionary(key => int.Parse(key.id), key => key.name); + } + public IEnumerable<(int Id, string Name, NpcData Data, List Dummy)> Parse() { + var npcNames = ParseNpcNames(); foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("npc/"))) { - reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeNpc(xmlReader.GetString(entry)))); - var root = NpcSerializer.Deserialize(reader) as NpcDataRoot; + var reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeNpc(xmlReader.GetString(entry)))); + var root = npcSerializer.Deserialize(reader) as NpcDataRoot; Debug.Assert(root != null); NpcData data = root.environment; if (data == null) continue; int npcId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (npcId, npcNames.GetValueOrDefault(npcId), data, root.effectdummy); + yield return (npcId, npcNames.GetValueOrDefault(npcId, string.Empty), data, root.effectdummy); + } + } + + public IEnumerable<(int Id, string Name, NpcDataKR Data, List Dummy)> ParseKr() { + var npcNames = ParseNpcNames(); + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("npcdata/"))) { + var reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeNpc(xmlReader.GetString(entry)))); + var rootKr = npcKrSerializer.Deserialize(reader) as NpcDataListKR; + Debug.Assert(rootKr != null); + + foreach (NpcDataRootKR item in rootKr.npcs) { + NpcDataKR dataKr = item.environment; + if (dataKr == null) continue; + + yield return (item.id, npcNames.GetValueOrDefault(item.id, string.Empty), dataKr, dataKr.effectdummy); + } } } } diff --git a/Maple2.File.Parser/PetParser.cs b/Maple2.File.Parser/PetParser.cs index ae91d48..fd9bf6b 100644 --- a/Maple2.File.Parser/PetParser.cs +++ b/Maple2.File.Parser/PetParser.cs @@ -37,7 +37,7 @@ public PetParser(M2dReader xmlReader) { if (data == null) continue; int petId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (petId, petNames.GetValueOrDefault(petId), data); + yield return (petId, petNames.GetValueOrDefault(petId, string.Empty), data); } } diff --git a/Maple2.File.Parser/QuestParser.cs b/Maple2.File.Parser/QuestParser.cs index fbdc4f6..9ff0416 100644 --- a/Maple2.File.Parser/QuestParser.cs +++ b/Maple2.File.Parser/QuestParser.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Xml; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.IO.Crypto.Common; using Maple2.File.Parser.Tools; @@ -17,10 +18,43 @@ public class QuestParser { public QuestParser(M2dReader xmlReader) { this.xmlReader = xmlReader; descriptionSerializer = new XmlSerializer(typeof(QuestDescriptionRoot)); - questSerializer = new XmlSerializer(typeof(QuestDataRootRoot)); + Type type = FeatureLocaleFilter.Locale == "KR" ? typeof(QuestDataRootKR) : typeof(QuestDataRootRoot); + questSerializer = new XmlSerializer(type); } public IEnumerable<(int Id, string Name, QuestData Data)> Parse() { + Dictionary questNames = ParseQuestDescriptions(); + + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("quest/"))) { + var reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeQuest(xmlReader.GetString(entry)))); + + var root = questSerializer.Deserialize(reader) as QuestDataRootRoot; + Debug.Assert(root != null); + + QuestData? data = root.environment?.quest; + if (data == null) continue; + + int questId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); + yield return (questId, questNames.GetValueOrDefault(questId, string.Empty), data); + } + } + + public IEnumerable<(int Id, string Name, QuestDataKR Data)> ParseKr() { + Dictionary questNames = ParseQuestDescriptions(); + + PackFileEntry? entry = xmlReader.GetEntry("questdata.xml"); + Debug.Assert(entry != null, "questdata.xml not found"); + var reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeQuest(xmlReader.GetString(entry)))); + + var root = questSerializer.Deserialize(reader) as QuestDataRootKR; + Debug.Assert(root != null); + + foreach (QuestDataKR data in root.quests) { + yield return (data.id, questNames.GetValueOrDefault(data.id, string.Empty), data); + } + } + + public Dictionary ParseQuestDescriptions() { Dictionary questNames = new(); foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("string/en/questdescription"))) { // Match match = Regex.Match(entry.Name, "questdescription_event(\\w{2})\\.xml"); @@ -38,16 +72,6 @@ public QuestParser(M2dReader xmlReader) { } } - foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("quest/"))) { - var reader = XmlReader.Create(new StringReader(Sanitizer.SanitizeQuest(xmlReader.GetString(entry)))); - var root = questSerializer.Deserialize(reader) as QuestDataRootRoot; - Debug.Assert(root != null); - - QuestData data = root.environment?.quest; - if (data == null) continue; - - int questId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (questId, questNames.GetValueOrDefault(questId), data); - } + return questNames; } } diff --git a/Maple2.File.Parser/RidingParser.cs b/Maple2.File.Parser/RidingParser.cs index b5c456a..3a0ab7b 100644 --- a/Maple2.File.Parser/RidingParser.cs +++ b/Maple2.File.Parser/RidingParser.cs @@ -12,11 +12,13 @@ public class RidingParser { private readonly M2dReader xmlReader; private readonly XmlSerializer ridingSerializer; private readonly XmlSerializer passengerRidingSerializer; + private readonly XmlSerializer ridingKRSerializer; public RidingParser(M2dReader xmlReader) { this.xmlReader = xmlReader; ridingSerializer = new XmlSerializer(typeof(RidingRoot)); passengerRidingSerializer = new XmlSerializer(typeof(PassengerRidingRoot)); + ridingKRSerializer = new XmlSerializer(typeof(RidingKRRoot)); } public IEnumerable<(int Id, Riding Data)> Parse() { @@ -48,4 +50,18 @@ public RidingParser(M2dReader xmlReader) { yield return (rideId, data); } } + + public IEnumerable<(int Id, RidingKR Data)> ParseKr() { + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("riding/"))) { + + var reader = XmlReader.Create(new StringReader(Sanitizer.RemoveEmpty(xmlReader.GetString(entry)))); + var root = ridingKRSerializer.Deserialize(reader) as RidingKRRoot; + Debug.Assert(root != null); + + RidingKR data = root.riding; + if (data == null || data.basic == null) continue; + + yield return (data.basic.id, data); + } + } } diff --git a/Maple2.File.Parser/ScriptParser.cs b/Maple2.File.Parser/ScriptParser.cs index da94a26..282747b 100644 --- a/Maple2.File.Parser/ScriptParser.cs +++ b/Maple2.File.Parser/ScriptParser.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.IO.Crypto.Common; using Maple2.File.Parser.Xml.Script; @@ -15,7 +16,7 @@ public class ScriptParser { public ScriptParser(M2dReader xmlReader) { this.xmlReader = xmlReader; - npcScriptSerializer = new XmlSerializer(typeof(NpcScript)); + npcScriptSerializer = new XmlSerializer(FeatureLocaleFilter.Locale == "KR" ? typeof(NpcScriptListKr) : typeof(NpcScript)); questScriptSerializer = new XmlSerializer(typeof(QuestScriptRoot)); scriptStringSerializer = new XmlSerializer(typeof(StringMapping)); } @@ -30,6 +31,17 @@ public ScriptParser(M2dReader xmlReader) { } } + public IEnumerable<(int Id, NpcScriptKR Script)> ParseNpcKr() { + var entry = xmlReader.GetEntry("npcscript_final.xml"); + Debug.Assert(entry != null); + var root = npcScriptSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as NpcScriptListKr; + Debug.Assert(root != null); + + foreach (NpcScriptKR npc in root.npcs) { + yield return (npc.id, npc); + } + } + public IEnumerable<(int Id, QuestScript Script)> ParseQuest() { foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("script/quest"))) { var root = questScriptSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as QuestScriptRoot; @@ -41,6 +53,17 @@ public ScriptParser(M2dReader xmlReader) { } } + public IEnumerable<(int Id, QuestScript Script)> ParseQuestKr() { + var entry = xmlReader.GetEntry("questscript_final.xml"); + Debug.Assert(entry != null); + var root = questScriptSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as QuestScriptRoot; + Debug.Assert(root != null); + + foreach (QuestScript quest in root.quest) { + yield return (quest.id, quest); + } + } + public IDictionary ParseStrings(string language = "en") { var result = new Dictionary(); string prefix = $"string/{language}/scriptnpc"; diff --git a/Maple2.File.Parser/SkillParser.cs b/Maple2.File.Parser/SkillParser.cs index 927c2c8..1f51d4f 100644 --- a/Maple2.File.Parser/SkillParser.cs +++ b/Maple2.File.Parser/SkillParser.cs @@ -17,10 +17,40 @@ public class SkillParser { public SkillParser(M2dReader xmlReader) { this.xmlReader = xmlReader; nameSerializer = new XmlSerializer(typeof(StringMapping)); - skillSerializer = new XmlSerializer(typeof(SkillData)); + Type type = FeatureLocaleFilter.Locale is "KR" ? typeof(SkillDataKR) : typeof(SkillData); + skillSerializer = new XmlSerializer(type); } public IEnumerable<(int Id, string Name, SkillData Data)> Parse() { + Dictionary skillNames = LoadSkillNames(); + + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("skill/"))) { + var data = skillSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as SkillData; + Debug.Assert(data != null); + + if (data.FeatureLocale() == null) continue; + + int skillId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); + yield return (skillId, skillNames.GetValueOrDefault(skillId, string.Empty), data); + } + } + + public IEnumerable<(int Id, string Name, SkillKR Data)> ParseKr() { + Dictionary skillNames = LoadSkillNames(); + + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("skilldata/"))) { + var data = skillSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as SkillDataKR; + Debug.Assert(data != null); + + if (data.FeatureLocale() == null) continue; + + foreach (SkillKR skill in data.Skills) { + yield return (skill.id, skillNames.GetValueOrDefault(skill.id, string.Empty), skill); + } + } + } + + public Dictionary LoadSkillNames() { Dictionary skillNames = new(); foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("string/en/skillname"))) { XmlReader reader = xmlReader.GetXmlReader(entry); @@ -32,14 +62,6 @@ public SkillParser(M2dReader xmlReader) { } } - foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.StartsWith("skill/"))) { - var data = skillSerializer.Deserialize(xmlReader.GetXmlReader(entry)) as SkillData; - Debug.Assert(data != null); - - if (data.FeatureLocale() == null) continue; - - int skillId = int.Parse(Path.GetFileNameWithoutExtension(entry.Name)); - yield return (skillId, skillNames.GetValueOrDefault(skillId), data); - } + return skillNames; } } diff --git a/Maple2.File.Parser/TableParser.cs b/Maple2.File.Parser/TableParser.cs index 3a4da61..f14f4ba 100644 --- a/Maple2.File.Parser/TableParser.cs +++ b/Maple2.File.Parser/TableParser.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Xml; using System.Xml.Serialization; +using M2dXmlGenerator; using Maple2.File.IO; using Maple2.File.Parser.Enum; using Maple2.File.Parser.Tools; @@ -45,6 +46,7 @@ public class TableParser { private readonly XmlSerializer itemSocketSerializer; private readonly XmlSerializer itemSocketScrollSerializer; private readonly XmlSerializer jobSerializer; + private readonly XmlSerializer jobKRSerializer; private readonly XmlSerializer magicPathSerializer; private readonly XmlSerializer mapSpawnTagSerializer; private readonly XmlSerializer masteryRecipeSerializer; @@ -58,8 +60,10 @@ public class TableParser { private readonly XmlSerializer premiumClubPackageSerializer; private readonly XmlSerializer setItemInfoSerializer; private readonly XmlSerializer setItemOptionSerializer; + private readonly XmlSerializer setItemOptionKRSerializer; private readonly XmlSerializer titleTagSerializer; private readonly XmlSerializer individualItemDropSerializer; + private readonly XmlSerializer individualItemDropKRSerializer; private readonly XmlSerializer gachaInfoSerializer; private readonly XmlSerializer shopBeautyCouponSerializer; private readonly XmlSerializer shopFurnishingSerializer; @@ -96,6 +100,8 @@ public class TableParser { private readonly XmlSerializer weddingSkillSerializer; private readonly XmlSerializer smartPushSerializer; + private readonly string locale; + public TableParser(M2dReader xmlReader) { this.xmlReader = xmlReader; nameSerializer = new XmlSerializer(typeof(StringMapping)); @@ -132,6 +138,7 @@ public TableParser(M2dReader xmlReader) { itemSocketSerializer = new XmlSerializer(typeof(ItemSocketRoot)); itemSocketScrollSerializer = new XmlSerializer(typeof(ItemSocketScrollRoot)); jobSerializer = new XmlSerializer(typeof(JobRoot)); + jobKRSerializer = new XmlSerializer(typeof(JobRootKR)); magicPathSerializer = new XmlSerializer(typeof(MagicPath)); mapSpawnTagSerializer = new XmlSerializer(typeof(MapSpawnTag)); masteryRecipeSerializer = new XmlSerializer(typeof(MasteryRecipeRoot)); @@ -145,8 +152,10 @@ public TableParser(M2dReader xmlReader) { premiumClubPackageSerializer = new XmlSerializer(typeof(PremiumClubPackageRoot)); setItemInfoSerializer = new XmlSerializer(typeof(SetItemInfoRoot)); setItemOptionSerializer = new XmlSerializer(typeof(SetItemOptionRoot)); + setItemOptionKRSerializer = new XmlSerializer(typeof(SetItemOptionRootKR)); titleTagSerializer = new XmlSerializer(typeof(TitleTagRoot)); individualItemDropSerializer = new XmlSerializer(typeof(IndividualItemDropRoot)); + individualItemDropKRSerializer = new XmlSerializer(typeof(IndividualItemDropRootKR)); gachaInfoSerializer = new XmlSerializer(typeof(GachaInfoRoot)); shopBeautyCouponSerializer = new XmlSerializer(typeof(ShopBeautyCouponRoot)); shopFurnishingSerializer = new XmlSerializer(typeof(ShopFurnishingRoot)); @@ -183,6 +192,8 @@ public TableParser(M2dReader xmlReader) { weddingSkillSerializer = new XmlSerializer(typeof(WeddingSkillRoot)); smartPushSerializer = new XmlSerializer(typeof(SmartPushRoot)); + locale = FeatureLocaleFilter.Locale.ToLower(); + // var seen = new HashSet(); // this.bankTypeSerializer.UnknownAttribute += (sender, args) => { // if (!seen.Contains(args.Attr.Name)) { @@ -245,7 +256,11 @@ public TableParser(M2dReader xmlReader) { } public IEnumerable<(int Id, DungeonRoom Dungeon)> ParseDungeonRoom() { - XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("table/na/dungeonroom.xml")); + string filename = "table/na/dungeonroom.xml"; + if (locale == "kr") { + filename = "table/dungeonroom.xml"; + } + XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry(filename)); var data = dungeonRoomSerializer.Deserialize(reader) as DungeonRoomRoot; Debug.Assert(data != null); @@ -285,7 +300,7 @@ public TableParser(M2dReader xmlReader) { } public IEnumerable ParseDungeonConfig() { - XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("table/na/dungeonconfig.xml")); + XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry($"table/{locale}/dungeonconfig.xml")); var data = dungeonConfigSerializer.Deserialize(reader) as DungeonConfigRoot; Debug.Assert(data != null); @@ -295,7 +310,7 @@ public IEnumerable ParseDungeonConfig() { } public IEnumerable ParseReverseRaidConfig() { - XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("table/na/dungeonconfig.xml")); + XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry($"table/{locale}/dungeonconfig.xml")); var data = dungeonConfigSerializer.Deserialize(reader) as DungeonConfigRoot; Debug.Assert(data != null); @@ -305,7 +320,7 @@ public IEnumerable ParseReverseRaidConfig() { } public IEnumerable ParseUnitedWeeklyReward() { - XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("table/na/dungeonconfig.xml")); + XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry($"table/{locale}/dungeonconfig.xml")); var data = dungeonConfigSerializer.Deserialize(reader) as DungeonConfigRoot; Debug.Assert(data != null); @@ -336,7 +351,7 @@ public IEnumerable ParseUnitedWeeklyReward() { Debug.Assert(data != null); foreach (Fish fish in data.fish) { - yield return (fish.id, fishNames.GetValueOrDefault(fish.id), fish); + yield return (fish.id, fishNames.GetValueOrDefault(fish.id, string.Empty), fish); } } @@ -475,7 +490,7 @@ public IEnumerable ParseUnitedWeeklyReward() { Debug.Assert(data != null); foreach (InteractObject interact in data.interact) { - yield return (interact.id, interactNames.GetValueOrDefault(interact.id), interact); + yield return (interact.id, interactNames.GetValueOrDefault(interact.id, string.Empty), interact); } } @@ -513,7 +528,11 @@ public IEnumerable ParseUnitedWeeklyReward() { } public IEnumerable<(int Id, ItemExtraction Extraction)> ParseItemExtraction() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/itemextraction.xml"))); + string filename = "table/na/itemextraction.xml"; + if (locale == "kr") { + filename = "table/itemextraction.xml"; + } + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry(filename))); var reader = XmlReader.Create(new StringReader(xml)); var data = itemExtractionSerializer.Deserialize(reader) as ItemExtractionRoot; Debug.Assert(data != null); @@ -524,7 +543,7 @@ public IEnumerable ParseUnitedWeeklyReward() { } public IEnumerable<(int ItemId, ItemGemstoneUpgrade Item)> ParseItemGemstoneUpgrade() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/itemgemstoneupgrade.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/itemgemstoneupgrade.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = itemGemstoneUpgradeSerializer.Deserialize(reader) as ItemGemstoneUpgradeRoot; Debug.Assert(data != null); @@ -535,7 +554,7 @@ public IEnumerable ParseUnitedWeeklyReward() { } public IEnumerable<(int ItemId, ItemLapenshardUpgrade Item)> ParseItemLapenshardUpgrade() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/itemlapenshardupgrade.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/itemlapenshardupgrade.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = itemLapenshardUpgradeSerializer.Deserialize(reader) as ItemLapenshardUpgradeRoot; Debug.Assert(data != null); @@ -596,6 +615,17 @@ public IEnumerable ParseJobTable() { } } + public IEnumerable ParseJobTableKR() { + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/job.xml"))); + var reader = XmlReader.Create(new StringReader(xml)); + var data = jobKRSerializer.Deserialize(reader) as JobRootKR; + Debug.Assert(data != null); + + foreach (JobTableKR job in data.job) { + yield return job; + } + } + public IEnumerable<(long Id, MagicType Type)> ParseMagicPath() { string sanitized = Sanitizer.SanitizeMagicPath(xmlReader.GetString(xmlReader.GetEntry("table/magicpath.xml"))); var data = magicPathSerializer.Deserialize(XmlReader.Create(new StringReader(sanitized))) as MagicPath; @@ -708,7 +738,7 @@ public IEnumerable ParseJobTable() { Debug.Assert(data != null); foreach (SetItemInfo info in data.set) { - yield return (info.id, setNames.GetValueOrDefault(info.id), info); + yield return (info.id, setNames.GetValueOrDefault(info.id, string.Empty), info); } } @@ -722,6 +752,18 @@ public IEnumerable ParseJobTable() { } } + public IEnumerable<(int Id, SetItemOptionKR Option)> ParseSetItemOptionKR() { + IO.Crypto.Common.PackFileEntry entry = xmlReader.GetEntry("table/setiteminfo.xml"); + var strinte = xmlReader.GetString(entry); + XmlReader reader = xmlReader.GetXmlReader(entry); + var data = setItemOptionKRSerializer.Deserialize(reader) as SetItemOptionRootKR; + Debug.Assert(data != null); + + foreach (SetItemOptionKR option in data.option) { + yield return (option.id, option); + } + } + public IEnumerable<(int Id, string Name, TitleTag TitleTag)> ParseTitleTag() { XmlReader nameReader = xmlReader.GetXmlReader(xmlReader.GetEntry("en/titlename.xml")); var mapping = nameSerializer.Deserialize(nameReader) as StringMapping; @@ -734,7 +776,7 @@ public IEnumerable ParseJobTable() { Debug.Assert(data != null); foreach (TitleTag title in data.key) { - yield return (title.id, titleNames.GetValueOrDefault(title.id), title); + yield return (title.id, titleNames.GetValueOrDefault(title.id, string.Empty), title); } } @@ -744,11 +786,31 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(individualItemDrop => new { individualItemDrop.individualDropBoxID, individualItemDrop.dropGroup }) + var groups = data.individualDropBox.GroupBy(individualItemDrop => new { + individualItemDrop.individualDropBoxID, + individualItemDrop.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); + } + } + + public IEnumerable<(int Id, IDictionary>)> ParseIndividualItemDropKR() { + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/individualitemdrop_final.xml"))); + xml = Sanitizer.SanitizeBool(xml); + xml = Sanitizer.RemoveUtf8Bom(xml); + var reader = XmlReader.Create(new StringReader(xml)); + var data = individualItemDropKRSerializer.Deserialize(reader) as IndividualItemDropRootKR; + Debug.Assert(data != null); + + foreach (IndividualItemDropBox dropBox in data.DropBoxes) { + yield return (dropBox.DropBoxID, dropBox.Groups + .GroupBy(g => (byte) g.DropGroupID) + .ToDictionary( + g => g.Key, + g => g.SelectMany(grp => grp.Items).ToList() + )); } } @@ -758,11 +820,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -772,11 +836,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -786,11 +852,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -800,11 +868,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -814,11 +884,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -828,11 +900,13 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -842,39 +916,45 @@ public IEnumerable ParseJobTable() { var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } public IEnumerable<(int Id, IDictionary>)> ParseIndividualItemDropGacha() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/individualitemdrop_gacha.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/individualitemdrop_gacha.xml"))); xml = Sanitizer.SanitizeBool(xml); var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } public IEnumerable<(int Id, IDictionary>)> ParseIndividualItemGearBox() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/individualitemdrop_gearbox.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/individualitemdrop_gearbox.xml"))); xml = Sanitizer.SanitizeBool(xml); var reader = XmlReader.Create(new StringReader(xml)); var data = individualItemDropSerializer.Deserialize(reader) as IndividualItemDropRoot; Debug.Assert(data != null); - var groups = data.individualDropBox.GroupBy(dropbox => new { dropbox.individualDropBoxID, dropbox.dropGroup }) + var groups = data.individualDropBox.GroupBy(dropbox => new { + dropbox.individualDropBoxID, + dropbox.dropGroup + }) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var group in groups) { - yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup). - ToDictionary(drop => drop.Key, drop => drop.ToList())); + yield return (group.Key.individualDropBoxID, group.Value.GroupBy(drop => drop.dropGroup).ToDictionary(drop => drop.Key, drop => drop.ToList())); } } @@ -901,8 +981,11 @@ public IEnumerable ParseJobTable() { } } + public IEnumerable<(int ItemId, ShopFurnishing UgcItem)> ParseFurnishingShopUgcAll() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/shop_ugcall.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/shop_ugcall.xml"))); + xml = Sanitizer.RemoveUtf8Bom(xml); + var reader = XmlReader.Create(new StringReader(xml)); var data = shopFurnishingSerializer.Deserialize(reader) as ShopFurnishingRoot; Debug.Assert(data != null); @@ -913,7 +996,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int ItemId, ShopFurnishing UgcItem)> ParseFurnishingShopMaid() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/shop_maid.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/shop_maid.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = shopFurnishingSerializer.Deserialize(reader) as ShopFurnishingRoot; Debug.Assert(data != null); @@ -924,7 +1007,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int CategoryId, MeretMarketCategory Category)> ParseMeretMarketCategory() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/meratmarketcategory.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/meratmarketcategory.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = meretmarketCategorySerializer.Deserialize(reader) as MeretMarketCategoryRoot; Debug.Assert(data != null); @@ -1002,7 +1085,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Id, UgcDesign Design)> ParseUgcDesign() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/ugcdesign.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/ugcdesign.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = ugcDesignSerializer.Deserialize(reader) as UgcDesignRoot; Debug.Assert(data != null); @@ -1035,7 +1118,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Id, Banner Banner)> ParseBanner() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/banner.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/banner.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = bannerSerializer.Deserialize(reader) as BannerRoot; Debug.Assert(data != null); @@ -1068,7 +1151,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Id, ChapterBook Book)> ParseChapterBook() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/chapterbook.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/chapterbook.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = chapterBookSerializer.Deserialize(reader) as ChapterBookRoot; @@ -1164,7 +1247,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Level, SurvivalLevel Entry)> ParseSurvivalLevel() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/survivallevel.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/survivallevel.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = survivalLevelSerializer.Deserialize(reader) as SurvivalLevelRoot; @@ -1230,7 +1313,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Id, FieldMission Mission)> ParseFieldMission() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/fieldmission.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/fieldmission.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = fieldMissionSerializer.Deserialize(reader) as FieldMissionRoot; Debug.Assert(data != null); @@ -1241,7 +1324,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(string Feature, IList Maps)> ParseWorldMap() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/newworldmap.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/newworldmap.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = worldMapSerializer.Deserialize(reader) as WorldMapRoot; Debug.Assert(data != null); @@ -1307,7 +1390,7 @@ public IEnumerable ParseJobTable() { } public IEnumerable<(int Id, SmartPush Button)> ParseSmartPush() { - string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/na/smartpush.xml"))); + string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/smartpush.xml"))); var reader = XmlReader.Create(new StringReader(xml)); var data = smartPushSerializer.Deserialize(reader) as SmartPushRoot; Debug.Assert(data != null); diff --git a/Maple2.File.Parser/Tools/Sanitizer.cs b/Maple2.File.Parser/Tools/Sanitizer.cs index 323a186..0559c08 100644 --- a/Maple2.File.Parser/Tools/Sanitizer.cs +++ b/Maple2.File.Parser/Tools/Sanitizer.cs @@ -95,4 +95,11 @@ private static string FixCommaFloats(string xml, params string[] attributes) { string pattern = $"({string.Join('|', attributes)})=\"(-?\\d+)(?:,(\\d+))\""; return Regex.Replace(xml, pattern, "$1=\"$2.$3\""); } + + public static string RemoveUtf8Bom(string xml) { + if (!string.IsNullOrEmpty(xml) && xml[0] == '\uFEFF') { + return xml[1..]; + } + return xml; + } } diff --git a/Maple2.File.Parser/Xml/Common/ItemOptionKR.cs b/Maple2.File.Parser/Xml/Common/ItemOptionKR.cs new file mode 100644 index 0000000..05f9cda --- /dev/null +++ b/Maple2.File.Parser/Xml/Common/ItemOptionKR.cs @@ -0,0 +1,493 @@ +using System.Xml.Serialization; + +namespace Maple2.File.Parser.Xml.Common; + +[XmlType(Namespace = "Common")] +public class ItemOptionKR { + #region StatValue + [XmlAttribute("str")] public int str_value_base; + [XmlAttribute("dex")] public int dex_value_base; + [XmlAttribute("int")] public int int_value_base; + [XmlAttribute("luk")] public int luk_value_base; + [XmlAttribute("hp")] public int hp_value_base; + [XmlAttribute("hp_rgp")] public int hp_rgp_value_base; + [XmlAttribute("hp_inv")] public int hp_inv_value_base; + [XmlAttribute("sp")] public int sp_value_base; + [XmlAttribute("sp_rgp")] public int sp_rgp_value_base; + [XmlAttribute("sp_inv")] public int sp_inv_value_base; + [XmlAttribute("ep")] public int ep_value_base; + [XmlAttribute("ep_rgp")] public int ep_rgp_value_base; + [XmlAttribute("ep_inv")] public int ep_inv_value_base; + [XmlAttribute("asp")] public int asp_value_base; + [XmlAttribute("msp")] public int msp_value_base; + [XmlAttribute("atp")] public int atp_value_base; + [XmlAttribute("evp")] public int evp_value_base; + [XmlAttribute("cap")] public int cap_value_base; + [XmlAttribute("cad")] public int cad_value_base; + [XmlAttribute("car")] public int car_value_base; + [XmlAttribute("ndd")] public int ndd_value_base; + [XmlAttribute("pap")] public int pap_value_base; + [XmlAttribute("map")] public int map_value_base; + [XmlAttribute("par")] public int par_value_base; + [XmlAttribute("mar")] public int mar_value_base; + [XmlAttribute("wapmin")] public int wapmin_value_base; + [XmlAttribute("wapmax")] public int wapmax_value_base; + [XmlAttribute("dmg")] public int dmg_value_base; + [XmlAttribute("rmsp")] public int rmsp_value_base; + [XmlAttribute("bap")] public int bap_value_base; + [XmlAttribute("bap_pet")] public int bap_pet_value_base; + + public int StatValue(byte i) => i switch { + 0 => str_value_base, + 1 => dex_value_base, + 2 => int_value_base, + 3 => luk_value_base, + 4 => hp_value_base, + 5 => hp_rgp_value_base, + 6 => hp_inv_value_base, + 7 => sp_value_base, + 8 => sp_rgp_value_base, + 9 => sp_inv_value_base, + 10 => ep_value_base, + 11 => ep_rgp_value_base, + 12 => ep_inv_value_base, + 13 => asp_value_base, + 14 => msp_value_base, + 15 => atp_value_base, + 16 => evp_value_base, + 17 => cap_value_base, + 18 => cad_value_base, + 19 => car_value_base, + 20 => ndd_value_base, + 23 => pap_value_base, + 24 => map_value_base, + 25 => par_value_base, + 26 => mar_value_base, + 27 => wapmin_value_base, + 28 => wapmax_value_base, + 29 => dmg_value_base, + 30 => dmg_value_base, + 32 => rmsp_value_base, + 33 => bap_value_base, + 34 => bap_pet_value_base, + _ => throw new ArgumentOutOfRangeException(nameof(i), i, null), + }; + #endregion + + #region StatRate + + [XmlAttribute("abp")] public float abp_rate_base; + [XmlAttribute("jmp")] public float jmp_rate_base; + [XmlAttribute("pen")] public float pen_rate_base; + + public float StatRate(byte i) => i switch { + 21 => abp_rate_base, + 22 => jmp_rate_base, + 31 => pen_rate_base, + _ => throw new ArgumentOutOfRangeException(nameof(i), i, null), + }; + #endregion + + #region SpecialValue + [XmlAttribute("dashDistance")] public int dashDistance; + [XmlAttribute("killHPRestore")] public int killHPRestore; + [XmlAttribute("killSPRestore")] public int killSPRestore; + [XmlAttribute("killEPRestore")] public int killEPRestore; + [XmlAttribute("KnockBackReduce")] public int KnockBackReduce; + [XmlAttribute("pvpdamageincrease")] public int pvpdamageincrease; + [XmlAttribute("pvpdamagereduce")] public int pvpdamagereduce; + [XmlAttribute("skill_levelup_tier_1")] public int skill_levelup_tier_1; + [XmlAttribute("skill_levelup_tier_2")] public int skill_levelup_tier_2; + [XmlAttribute("skill_levelup_tier_3")] public int skill_levelup_tier_3; + [XmlAttribute("skill_levelup_tier_4")] public int skill_levelup_tier_4; + [XmlAttribute("skill_levelup_tier_5")] public int skill_levelup_tier_5; + [XmlAttribute("skill_levelup_tier_6")] public int skill_levelup_tier_6; + [XmlAttribute("skill_levelup_tier_7")] public int skill_levelup_tier_7; + [XmlAttribute("skill_levelup_tier_8")] public int skill_levelup_tier_8; + [XmlAttribute("skill_levelup_tier_9")] public int skill_levelup_tier_9; + [XmlAttribute("skill_levelup_tier_10")] public int skill_levelup_tier_10; + [XmlAttribute("skill_levelup_tier_11")] public int skill_levelup_tier_11; + [XmlAttribute("skill_levelup_tier_12")] public int skill_levelup_tier_12; + [XmlAttribute("skill_levelup_tier_13")] public int skill_levelup_tier_13; + [XmlAttribute("skill_levelup_tier_14")] public int skill_levelup_tier_14; + [XmlAttribute("improve_massive_ox_msp")] public int improve_massive_ox_msp; + [XmlAttribute("improve_massive_trapmaster_msp")] public int improve_massive_trapmaster_msp; + [XmlAttribute("improve_massive_finalsurvival_msp")] public int improve_massive_finalsurvival_msp; + [XmlAttribute("improve_massive_crazyrunner_msp")] public int improve_massive_crazyrunner_msp; + [XmlAttribute("improve_massive_escape_msp")] public int improve_massive_escape_msp; + [XmlAttribute("improve_massive_springbeach_msp")] public int improve_massive_springbeach_msp; + [XmlAttribute("improve_massive_dancedance_msp")] public int improve_massive_dancedance_msp; + [XmlAttribute("complete_fieldmission_msp")] public int complete_fieldmission_msp; + [XmlAttribute("additionaleffect_95000012")] public int additionaleffect_95000012; + [XmlAttribute("additionaleffect_95000014")] public int additionaleffect_95000014; + [XmlAttribute("improve_chaosraid_asp")] public int improve_chaosraid_asp; + [XmlAttribute("improve_chaosraid_atp")] public int improve_chaosraid_atp; + [XmlAttribute("improve_chaosraid_hp")] public int improve_chaosraid_hp; + [XmlAttribute("improve_pettrap_reward")] public int improve_pettrap_reward; + [XmlAttribute("improve_massive_sh_crazyrunner_msp")] public int improve_massive_sh_crazyrunner_msp; + [XmlAttribute("defensive_damageV")] public int defensive_damageV; + [XmlAttribute("cap_ignore_limit")] public int cap_ignore_limit; + [XmlAttribute("cad_ignore_limit")] public int cad_ignore_limit; + [XmlAttribute("improve_stat_major")] public int improve_stat_major; + + + public int SpecialValue(byte i) => i switch { + 4 => dashDistance, + 13 => killHPRestore, + 14 => killSPRestore, + 15 => killEPRestore, + 39 => KnockBackReduce, + 54 => pvpdamageincrease, + 55 => pvpdamagereduce, + 77 => skill_levelup_tier_1, + 78 => skill_levelup_tier_2, + 79 => skill_levelup_tier_3, + 80 => skill_levelup_tier_4, + 81 => skill_levelup_tier_5, + 82 => skill_levelup_tier_6, + 83 => skill_levelup_tier_7, + 84 => skill_levelup_tier_8, + 85 => skill_levelup_tier_9, + 86 => skill_levelup_tier_10, + 87 => skill_levelup_tier_11, + 88 => skill_levelup_tier_12, + 89 => skill_levelup_tier_13, + 90 => skill_levelup_tier_14, + 98 => improve_massive_ox_msp, + 99 => improve_massive_trapmaster_msp, + 100 => improve_massive_finalsurvival_msp, + 101 => improve_massive_crazyrunner_msp, + 102 => improve_massive_escape_msp, + 103 => improve_massive_springbeach_msp, + 104 => improve_massive_dancedance_msp, + 114 => complete_fieldmission_msp, + 117 => additionaleffect_95000012, + 118 => additionaleffect_95000014, + 148 => improve_chaosraid_asp, + 149 => improve_chaosraid_atp, + 150 => improve_chaosraid_hp, + 152 => str_value_base, + 153 => dex_value_base, + 154 => int_value_base, + 155 => luk_value_base, + 156 => improve_pettrap_reward, + 162 => improve_massive_sh_crazyrunner_msp, + 171 => defensive_damageV, + 180 => hp_value_base, + 181 => hp_rgp_value_base, + 182 => sp_value_base, + 183 => sp_rgp_value_base, + 184 => ep_value_base, + 185 => ep_inv_value_base, + 186 => asp_value_base, + 187 => msp_value_base, + 188 => atp_value_base, + 189 => evp_value_base, + 190 => cap_value_base, + 191 => cad_value_base, + 192 => car_value_base, + 193 => ndd_value_base, + 195 => pap_value_base, + 196 => map_value_base, + 197 => par_value_base, + 198 => mar_value_base, + 200 => rmsp_value_base, + 201 => bap_value_base, + 202 => cap_ignore_limit, + 203 => cad_ignore_limit, + 207 => improve_stat_major, + _ => throw new ArgumentOutOfRangeException(nameof(i), i, null), + }; + #endregion + + #region SpecialRate + [XmlAttribute("seg")] public float seg; + [XmlAttribute("smd")] public float smd; + [XmlAttribute("sss")] public float sss; + [XmlAttribute("finalAttackPower")] public float finalAttackPower; + [XmlAttribute("wapRate")] public float wapRate; + [XmlAttribute("finalAdditionalDamage")] public float finalAdditionalDamage; + [XmlAttribute("cri")] public float cri; + [XmlAttribute("sgi")] public float sgi; + [XmlAttribute("atpToBap")] public float atpToBap; + [XmlAttribute("sgi_elite")] public float sgi_elite; + [XmlAttribute("sgi_boss")] public float sgi_boss; + [XmlAttribute("heal")] public float heal; + [XmlAttribute("receivedhealincrease")] public float receivedhealincrease; + [XmlAttribute("iceDamage")] public float iceDamage; + [XmlAttribute("fireDamage")] public float fireDamage; + [XmlAttribute("darkDamage")] public float darkDamage; + [XmlAttribute("lightDamage")] public float lightDamage; + [XmlAttribute("poisonDamage")] public float poisonDamage; + [XmlAttribute("thunderDamage")] public float thunderDamage; + [XmlAttribute("nddincrease")] public float nddincrease; + [XmlAttribute("lddincrease")] public float lddincrease; + [XmlAttribute("parpen")] public float parpen; + [XmlAttribute("marpen")] public float marpen; + [XmlAttribute("icedamagereduce")] public float icedamagereduce; + [XmlAttribute("firedamagereduce")] public float firedamagereduce; + [XmlAttribute("darkdamagereduce")] public float darkdamagereduce; + [XmlAttribute("lightdamagereduce")] public float lightdamagereduce; + [XmlAttribute("poisondamagereduce")] public float poisondamagereduce; + [XmlAttribute("thunderdamagereduce")] public float thunderdamagereduce; + [XmlAttribute("stunReduce")] public float stunReduce; + [XmlAttribute("skillCooldown")] public float skillCooldown; + [XmlAttribute("conditionReduce")] public float conditionReduce; + [XmlAttribute("nearDistanceDamageReduce")] public float nearDistanceDamageReduce; + [XmlAttribute("longDistanceDamageReduce")] public float longDistanceDamageReduce; + [XmlAttribute("strRate")] public float strRate; + [XmlAttribute("dexRate")] public float dexRate; + [XmlAttribute("intRate")] public float intRate; + [XmlAttribute("lukRate")] public float lukRate; + [XmlAttribute("hpRate")] public float hpRate; + [XmlAttribute("hpInvRate")] public float hpInvRate; + [XmlAttribute("spRate")] public float spRate; + [XmlAttribute("spInvRate")] public float spInvRate; + [XmlAttribute("npcKillDropItemIncRate")] public float npcKillDropItemIncRate; + [XmlAttribute("seg_questReward")] public float seg_questReward; + [XmlAttribute("epRate")] public float epRate; + [XmlAttribute("epInvRate")] public float epInvRate; + [XmlAttribute("aspRate")] public float aspRate; + [XmlAttribute("mspRate")] public float mspRate; + [XmlAttribute("improveguildexp")] public float improveguildexp; + [XmlAttribute("improveguildcoin")] public float improveguildcoin; + [XmlAttribute("improvemassiveeventbexpball")] public float improvemassiveeventbexpball; + [XmlAttribute("seg_fishingReward")] public float seg_fishingReward; + [XmlAttribute("seg_arcadeReward")] public float seg_arcadeReward; + [XmlAttribute("seg_playinstrumentReward")] public float seg_playinstrumentReward; + [XmlAttribute("improve_maid_mood")] public float improve_maid_mood; + [XmlAttribute("reduce_maid_recipe")] public float reduce_maid_recipe; + [XmlAttribute("reduce_meso_trade_fee")] public float reduce_meso_trade_fee; + [XmlAttribute("reduce_enchant_matrial_fee")] public float reduce_enchant_matrial_fee; + [XmlAttribute("reduce_merat_revival_fee")] public float reduce_merat_revival_fee; + [XmlAttribute("improve_mining_reward_item")] public float improve_mining_reward_item; + [XmlAttribute("improve_breeding_reward_item")] public float improve_breeding_reward_item; + [XmlAttribute("improve_blacksmithing_reward_mastery")] public float improve_blacksmithing_reward_mastery; + [XmlAttribute("improve_engraving_reward_mastery")] public float improve_engraving_reward_mastery; + [XmlAttribute("improve_gathering_reward_item")] public float improve_gathering_reward_item; + [XmlAttribute("improve_farming_reward_item")] public float improve_farming_reward_item; + [XmlAttribute("improve_alchemist_reward_mastery")] public float improve_alchemist_reward_mastery; + [XmlAttribute("improve_cooking_reward_mastery")] public float improve_cooking_reward_mastery; + [XmlAttribute("improve_acquire_gathering_exp")] public float improve_acquire_gathering_exp; + [XmlAttribute("improve_acquire_manufacturing_exp")] public float improve_acquire_manufacturing_exp; + [XmlAttribute("improve_massive_ox_exp")] public float improve_massive_ox_exp; + [XmlAttribute("improve_massive_trapmaster_exp")] public float improve_massive_trapmaster_exp; + [XmlAttribute("improve_massive_finalsurvival_exp")] public float improve_massive_finalsurvival_exp; + [XmlAttribute("improve_massive_crazyrunner_exp")] public float improve_massive_crazyrunner_exp; + [XmlAttribute("improve_massive_escape_exp")] public float improve_massive_escape_exp; + [XmlAttribute("improve_massive_springbeach_exp")] public float improve_massive_springbeach_exp; + [XmlAttribute("improve_massive_dancedance_exp")] public float improve_massive_dancedance_exp; + [XmlAttribute("npc_hit_reward_sp_ball")] public float npc_hit_reward_sp_ball; + [XmlAttribute("npc_hit_reward_ep_ball")] public float npc_hit_reward_ep_ball; + [XmlAttribute("improve_honor_token")] public float improve_honor_token; + [XmlAttribute("improve_pvp_exp")] public float improve_pvp_exp; + [XmlAttribute("improve_darkstream_damage")] public float improve_darkstream_damage; + [XmlAttribute("reduce_darkstream_recive_damage")] public float reduce_darkstream_recive_damage; + [XmlAttribute("strToInt")] public float strToInt; + [XmlAttribute("fishing_double_mastery")] public float fishing_double_mastery; + [XmlAttribute("playinstrument_double_mastery")] public float playinstrument_double_mastery; + [XmlAttribute("improve_glide_vertical_velocity")] public float improve_glide_vertical_velocity; + [XmlAttribute("rmspRate")] public float rmspRate; + [XmlAttribute("atpRate")] public float atpRate; + [XmlAttribute("evpRate")] public float evpRate; + [XmlAttribute("capRate")] public float capRate; + [XmlAttribute("carRate")] public float carRate; + [XmlAttribute("nddRate")] public float nddRate; + [XmlAttribute("jmpRate")] public float jmpRate; + [XmlAttribute("papRate")] public float papRate; + [XmlAttribute("mapRate")] public float mapRate; + [XmlAttribute("parRate")] public float parRate; + [XmlAttribute("marRate")] public float marRate; + [XmlAttribute("reduce_recovery_ep_inv")] public float reduce_recovery_ep_inv; + [XmlAttribute("improve_stat_wap_u")] public float improve_stat_wap_u; + [XmlAttribute("mining_double_reward")] public float mining_double_reward; + [XmlAttribute("breeding_double_reward")] public float breeding_double_reward; + [XmlAttribute("gathering_double_reward")] public float gathering_double_reward; + [XmlAttribute("farming_double_reward")] public float farming_double_reward; + [XmlAttribute("blacksmithing_double_reward")] public float blacksmithing_double_reward; + [XmlAttribute("engraving_double_reward")] public float engraving_double_reward; + [XmlAttribute("alchemist_double_reward")] public float alchemist_double_reward; + [XmlAttribute("cooking_double_reward")] public float cooking_double_reward; + [XmlAttribute("mining_double_mastery")] public float mining_double_mastery; + [XmlAttribute("breeding_double_mastery")] public float breeding_double_mastery; + [XmlAttribute("gathering_double_mastery")] public float gathering_double_mastery; + [XmlAttribute("farming_double_mastery")] public float farming_double_mastery; + [XmlAttribute("blacksmithing_double_mastery")] public float blacksmithing_double_mastery; + [XmlAttribute("engraving_double_mastery")] public float engraving_double_mastery; + [XmlAttribute("alchemist_double_mastery")] public float alchemist_double_mastery; + [XmlAttribute("cooking_double_mastery")] public float cooking_double_mastery; + [XmlAttribute("improve_chaosraid_wap")] public float improve_chaosraid_wap; + [XmlAttribute("improve_recovery_ball")] public float improve_recovery_ball; + [XmlAttribute("mining_multiaction")] public float mining_multiaction; + [XmlAttribute("breeding_multiaction")] public float breeding_multiaction; + [XmlAttribute("gathering_multiaction")] public float gathering_multiaction; + [XmlAttribute("farming_multiaction")] public float farming_multiaction; + [XmlAttribute("improve_massive_sh_crazyrunner_exp")] public float improve_massive_sh_crazyrunner_exp; + [XmlAttribute("reduce_damage_by_targetmaxhp")] public float reduce_damage_by_targetmaxhp; + [XmlAttribute("reduce_meso_revival_fee")] public float reduce_meso_revival_fee; + [XmlAttribute("improve_riding_run_speed")] public float improve_riding_run_speed; + [XmlAttribute("improve_dungeon_reward_meso")] public float improve_dungeon_reward_meso; + [XmlAttribute("improve_shop_buying_meso")] public float improve_shop_buying_meso; + [XmlAttribute("improve_itembox_reward_meso")] public float improve_itembox_reward_meso; + [XmlAttribute("reduce_remakeoption_fee")] public float reduce_remakeoption_fee; + [XmlAttribute("reduce_airtaxi_fee")] public float reduce_airtaxi_fee; + [XmlAttribute("reduce_gemstone_upgrade_fee")] public float reduce_gemstone_upgrade_fee; + [XmlAttribute("reduce_pet_remakeoption_fee")] public float reduce_pet_remakeoption_fee; + [XmlAttribute("improve_riding_speed")] public float improve_riding_speed; + [XmlAttribute("defensive_physicaldamage")] public float defensive_physicaldamage; + [XmlAttribute("defensive_magicaldamage")] public float defensive_magicaldamage; + [XmlAttribute("offensive_physicaldamage")] public float offensive_physicaldamage; + [XmlAttribute("offensive_magicaldamage")] public float offensive_magicaldamage; + [XmlAttribute("reduce_gameitem_socket_unlock_fee")] public float reduce_gameitem_socket_unlock_fee; + [XmlAttribute("aevp")] public float aevp; + [XmlAttribute("cap_ignore_limit_extra")] public float cap_ignore_limit_extra; + [XmlAttribute("reduce_do_heal_hp")] public float reduce_do_heal_hp; + + public float SpecialRate(byte i) => i switch { + 1 => seg, + 2 => smd, + 3 => sss, + 5 => finalAttackPower, + 6 => wapRate, + 7 => finalAdditionalDamage, + 8 => cri, + 9 => sgi, + 10 => atpToBap, + 11 => sgi_elite, + 12 => sgi_boss, + 16 => heal, + 17 => receivedhealincrease, + 18 => iceDamage, + 19 => fireDamage, + 20 => darkDamage, + 21 => lightDamage, + 22 => poisonDamage, + 23 => thunderDamage, + 24 => nddincrease, + 25 => lddincrease, + 26 => parpen, + 27 => marpen, + 28 => icedamagereduce, + 29 => firedamagereduce, + 30 => darkdamagereduce, + 31 => lightdamagereduce, + 32 => poisondamagereduce, + 33 => thunderdamagereduce, + 34 => stunReduce, + 35 => skillCooldown, + 36 => conditionReduce, + 37 => nearDistanceDamageReduce, + 38 => longDistanceDamageReduce, + 40 => strRate, + 41 => dexRate, + 42 => intRate, + 43 => lukRate, + 44 => hpRate, + 45 => hpInvRate, + 46 => spRate, + 47 => spInvRate, + 48 => npcKillDropItemIncRate, + 49 => seg_questReward, + 50 => epRate, + 51 => epInvRate, + 52 => aspRate, + 53 => mspRate, + 56 => improveguildexp, + 57 => improveguildcoin, + 58 => improvemassiveeventbexpball, + 59 => seg_fishingReward, + 60 => seg_arcadeReward, + 61 => seg_playinstrumentReward, + 62 => improve_maid_mood, + 63 => reduce_maid_recipe, + 64 => reduce_meso_trade_fee, + 65 => reduce_enchant_matrial_fee, + 66 => reduce_merat_revival_fee, + 67 => improve_mining_reward_item, + 68 => improve_breeding_reward_item, + 69 => improve_blacksmithing_reward_mastery, + 70 => improve_engraving_reward_mastery, + 71 => improve_gathering_reward_item, + 72 => improve_farming_reward_item, + 73 => improve_alchemist_reward_mastery, + 74 => improve_cooking_reward_mastery, + 75 => improve_acquire_gathering_exp, + 76 => improve_acquire_manufacturing_exp, + 91 => improve_massive_ox_exp, + 92 => improve_massive_trapmaster_exp, + 93 => improve_massive_finalsurvival_exp, + 94 => improve_massive_crazyrunner_exp, + 95 => improve_massive_escape_exp, + 96 => improve_massive_springbeach_exp, + 97 => improve_massive_dancedance_exp, + 105 => npc_hit_reward_sp_ball, + 106 => npc_hit_reward_ep_ball, + 107 => improve_honor_token, + 108 => improve_pvp_exp, + 109 => improve_darkstream_damage, + 110 => reduce_darkstream_recive_damage, + 111 => strToInt, + 112 => fishing_double_mastery, + 113 => playinstrument_double_mastery, + 115 => improve_glide_vertical_velocity, + 116 => rmspRate, + 119 => atpRate, + 120 => evpRate, + 121 => capRate, + 122 => carRate, + 123 => nddRate, + 124 => jmpRate, + 125 => papRate, + 126 => mapRate, + 127 => parRate, + 128 => marRate, + 129 => reduce_recovery_ep_inv, + 130 => improve_stat_wap_u, + 131 => mining_double_reward, + 132 => breeding_double_reward, + 133 => gathering_double_reward, + 134 => farming_double_reward, + 135 => blacksmithing_double_reward, + 136 => engraving_double_reward, + 137 => alchemist_double_reward, + 138 => cooking_double_reward, + 139 => mining_double_mastery, + 140 => breeding_double_mastery, + 141 => gathering_double_mastery, + 142 => farming_double_mastery, + 143 => blacksmithing_double_mastery, + 144 => engraving_double_mastery, + 145 => alchemist_double_mastery, + 146 => cooking_double_mastery, + 147 => improve_chaosraid_wap, + 151 => improve_recovery_ball, + 157 => mining_multiaction, + 158 => breeding_multiaction, + 159 => gathering_multiaction, + 160 => farming_multiaction, + 161 => improve_massive_sh_crazyrunner_exp, + 163 => reduce_damage_by_targetmaxhp, + 164 => reduce_meso_revival_fee, + 165 => improve_riding_run_speed, + 166 => improve_dungeon_reward_meso, + 167 => improve_shop_buying_meso, + 168 => improve_itembox_reward_meso, + 169 => reduce_remakeoption_fee, + 170 => reduce_airtaxi_fee, + 172 => reduce_gemstone_upgrade_fee, + 173 => reduce_pet_remakeoption_fee, + 174 => improve_riding_speed, + 175 => defensive_physicaldamage, + 176 => defensive_magicaldamage, + 177 => offensive_physicaldamage, + 178 => offensive_magicaldamage, + 179 => reduce_gameitem_socket_unlock_fee, + 194 => abp_rate_base, + 199 => pen_rate_base, + 204 => aevp, + 205 => cap_ignore_limit_extra, + 206 => reduce_do_heal_hp, + _ => throw new ArgumentOutOfRangeException(nameof(i), i, null), + }; + #endregion +} diff --git a/Maple2.File.Parser/Xml/Item/Item.cs b/Maple2.File.Parser/Xml/Item/Item.cs index 881f208..c296ac6 100644 --- a/Maple2.File.Parser/Xml/Item/Item.cs +++ b/Maple2.File.Parser/Xml/Item/Item.cs @@ -40,3 +40,46 @@ public partial class ItemData : IFeatureLocale { [XmlElement] public Housing housing; [XmlElement] public Shop Shop; } + +// ./data/xml/itemdata/%03d.xml +[XmlRoot("ms2")] +public partial class ItemDataKR { + [XmlElement("item")] public List items; +} + +public partial class ItemDataRootKR { + [XmlAttribute] public int id; + [M2dFeatureLocale] private ItemData _environment; +} + +public partial class ItemDataKR : IFeatureLocale { + [XmlElement] public Basic basic; + [XmlElement] public Slots slots; + [XmlElement] public Customize customize; + [XmlElement] public Mutation mutation; + [XmlElement] public Cutting cutting; + [XmlElement] public Install install; + [XmlElement] public Property property; + [XmlElement] public Material material; + [XmlElement] public Life life; + [XmlElement] public Limit limit; + [XmlElement] public Skill skill; + [XmlElement] public Skill objectWeaponSkill; + [XmlElement] public Title title; + [XmlElement] public Drop drop; + [XmlElement] public UCC ucc; + [XmlElement] public Effect effect; + [XmlElement] public Fusion fusion; + [XmlElement] public Pet pet; + [XmlElement] public Ride ride; + [XmlElement] public Badge gem; + [XmlElement] public AdditionalEffect AdditionalEffect; + [XmlElement] public Function function; + [XmlElement] public Tool tool; + [XmlElement] public Option option; + [XmlElement] public Maid maid; + [XmlElement] public PCBang PCBang; + [XmlElement] public MusicScore MusicScore; + [XmlElement] public Housing housing; + [XmlElement] public Shop Shop; +} diff --git a/Maple2.File.Parser/Xml/Item/Property.cs b/Maple2.File.Parser/Xml/Item/Property.cs index 47dceaf..e9f5de3 100644 --- a/Maple2.File.Parser/Xml/Item/Property.cs +++ b/Maple2.File.Parser/Xml/Item/Property.cs @@ -42,7 +42,7 @@ public partial class Property { [M2dArray] public int[] globalRePackingScrollID; [XmlAttribute] public int socketDataId; [XmlAttribute] public string functionTags = string.Empty; - [XmlAttribute] public int moveDisable; + [XmlAttribute] public bool moveDisable; [XmlAttribute] public bool disableDrop; [XmlElement] public Sell sell; diff --git a/Maple2.File.Parser/Xml/ItemOptionConstant.cs b/Maple2.File.Parser/Xml/ItemOptionConstant.cs index cc0835b..1a9bf31 100644 --- a/Maple2.File.Parser/Xml/ItemOptionConstant.cs +++ b/Maple2.File.Parser/Xml/ItemOptionConstant.cs @@ -24,3 +24,29 @@ public partial class ItemOptionConstantData : ItemOption, IFeatureLocale { [XmlAttribute] public int sgi_target; } + + +// ./data/xml/table/itemoptionconstant.xml +[XmlRoot("ms2")] +public partial class ItemOptionConstantRootKR { + [XmlElement("option")] public List options = []; +} + +public partial class ItemOptionConstant { + [XmlAttribute] public int code; + + [XmlElement("rank")] public List ranks = []; +} + +public partial class ItemOptionConstantRank { + [XmlAttribute] public int grade; + [XmlAttribute] public int createType; + + [XmlElement("v")] public List options = []; +} + +public partial class ItemOptionConstantDataKR { + [XmlAttribute] public string name = string.Empty; //abp, asp, atp, bap, bap_pet, cad, cap, car, conditionreduce, dex, evp, finaladditionaldamage, firedamage, heal, hp, improve_darkstream_damage, improve_honor_token, improve_pvp_exp, int, lddincrease, longdistancedamagereduce, luk, map, mar, marpen, msp, ndd, nddincrease, neardistancedamagereduce, pap, par, parpen, pen, poisondamage, pvpdamageincrease, pvpdamagereduce, reduce_darkstream_recive_damage, sgi_boss, sgi_elite, skillcooldown, sss, str, stunreduce, thunderdamage, wapmax, wapmin, wapRate, + [XmlAttribute] public int value; + [XmlAttribute] public int luaIndex; //?? +} diff --git a/Maple2.File.Parser/Xml/ItemOptionRandom.cs b/Maple2.File.Parser/Xml/ItemOptionRandom.cs new file mode 100644 index 0000000..9c4d4e7 --- /dev/null +++ b/Maple2.File.Parser/Xml/ItemOptionRandom.cs @@ -0,0 +1,23 @@ +// ./data/xml/table/itemoptionconstant.xml +using System.Xml.Serialization; + +[XmlRoot("ms2")] +public partial class ItemOptionRandomRootKR { + [XmlElement("option")] public List options = []; +} + +public partial class ItemOptionRandomKR { + [XmlAttribute] public int code; + [XmlAttribute] public int copyID; + [XmlAttribute] public bool isRarePickOne; + [XmlAttribute] public int levelGroupID; + [XmlAttribute] public int pickCount; + [XmlAttribute] public string statGroup = string.Empty; + + [XmlElement("rank")] public List ranks = []; +} + +public partial class ItemOptionRandomDataKR { + [XmlAttribute] public string name = string.Empty; //additionaleffect_95000012, additionaleffect_95000014, asp, atp, breeding_double_mastery, cad, cap, car, complete_fieldmission_msp, conditionreduce, darkdamage, darkdamagereduce, dex, evp, farming_double_mastery, finaladditionaldamage, firedamage, firedamagereduce, fishing_double_mastery, gathering_double_mastery, heal, hp, icedamage, icedamagereduce, improve_glide_vertical_velocity, improve_massive_crazyrunner_exp, improve_massive_crazyrunner_msp, improve_massive_dancedance_exp, improve_massive_dancedance_msp, improve_massive_escape_exp, improve_massive_escape_msp, improve_massive_finalsurvival_exp, improve_massive_finalsurvival_msp, improve_massive_ox_exp, improve_massive_ox_msp, improve_massive_springbeach_exp, improve_massive_springbeach_msp, improve_massive_trapmaster_exp, improve_massive_trapmaster_msp, int, killhprestore, knockbackreduce, lddincrease, lightdamage, lightdamagereduce, longdistancedamagereduce, luk, map, mar, marpen, mining_double_mastery, msp, nddincrease, neardistancedamagereduce, npc_hit_reward_ep_ball, npc_hit_reward_sp_ball, npckilldropitemincrate, pap, par, parpen, pen, playinstrument_double_mastery, poisondamage, poisondamagereduce, receivedhealincrease, seg_fishingreward, seg_playinstrumentreward, sgi_boss, skillcooldown, smd, str, stunreduce, thunderdamage, thunderdamagereduce, + [XmlAttribute] public int statID; +} diff --git a/Maple2.File.Parser/Xml/Map/Map.cs b/Maple2.File.Parser/Xml/Map/Map.cs index 5914460..42ed1ce 100644 --- a/Maple2.File.Parser/Xml/Map/Map.cs +++ b/Maple2.File.Parser/Xml/Map/Map.cs @@ -26,3 +26,15 @@ public partial class MapData : IFeatureLocale { [XmlElement] public Optimize optimize; [XmlElement] public WorldMap worldmap; // Ignored by client. } + +// .data/xml/table/fielddata.xml +[XmlRoot("ms2")] +public partial class MapDataRootKR { + // list of fieldData with ID as mapId, then inside its environment as MapDataRoot + [XmlElement("fieldData")] public List fieldData = []; +} + +public partial class MapDataRootKR { + [XmlAttribute] public int id; + [M2dFeatureLocale] private MapData _environment; +} diff --git a/Maple2.File.Parser/Xml/Npc/Npc.cs b/Maple2.File.Parser/Xml/Npc/Npc.cs index 1014b39..fe07129 100644 --- a/Maple2.File.Parser/Xml/Npc/Npc.cs +++ b/Maple2.File.Parser/Xml/Npc/Npc.cs @@ -38,3 +38,17 @@ public partial class NpcData : IFeatureLocale { [XmlElement] public Corpse corpse; [XmlElement] public Ride ride; // Ignored by client. } + +[XmlRoot("ms2")] +public partial class NpcDataListKR { + [XmlElement("npc")] public List npcs; +} + +public partial class NpcDataRootKR { + [XmlAttribute] public int id; + [XmlElement] public NpcDataKR environment; +} + +public partial class NpcDataKR : NpcData { + [XmlElement] public List effectdummy; +} diff --git a/Maple2.File.Parser/Xml/Quest/Quest.cs b/Maple2.File.Parser/Xml/Quest/Quest.cs index 51c4967..e95fa5a 100644 --- a/Maple2.File.Parser/Xml/Quest/Quest.cs +++ b/Maple2.File.Parser/Xml/Quest/Quest.cs @@ -52,3 +52,13 @@ public partial class Complete { [XmlAttribute] public int fieldID; } } + + +[XmlRoot("ms2")] +public partial class QuestDataRootKR { + [XmlElement("quest")] public List quests; +} + +public partial class QuestDataKR : QuestData, IFeatureLocale { + [XmlAttribute] public int id; +} diff --git a/Maple2.File.Parser/Xml/Riding/Riding.cs b/Maple2.File.Parser/Xml/Riding/Riding.cs index c5fa249..4d34f52 100644 --- a/Maple2.File.Parser/Xml/Riding/Riding.cs +++ b/Maple2.File.Parser/Xml/Riding/Riding.cs @@ -18,3 +18,14 @@ public partial class Riding : IFeatureLocale { [XmlElement] public StatValue stat; [XmlElement] public FaceCamera faceCamera; } + +// KMS2: ./data/xml/riding/%08d.xml +[XmlRoot("ms2")] +public class RidingKRRoot { + [XmlElement("riding")] public RidingKR riding; +} + +public class RidingKR : Riding { + [XmlElement("passengers")] public List passengers; +} + diff --git a/Maple2.File.Parser/Xml/Script/NpcScript.cs b/Maple2.File.Parser/Xml/Script/NpcScript.cs index c0a00a0..f871c7d 100644 --- a/Maple2.File.Parser/Xml/Script/NpcScript.cs +++ b/Maple2.File.Parser/Xml/Script/NpcScript.cs @@ -11,3 +11,12 @@ public partial class NpcScript { [M2dFeatureLocale(Selector = "id")] private IList _monologue; [M2dFeatureLocale(Selector = "id")] private IList _script; } + +[XmlRoot("ms2")] +public partial class NpcScriptListKr { + [XmlElement("npc")] public List npcs; +} + +public partial class NpcScriptKR : NpcScript { + [XmlAttribute("id")] public int id; +} diff --git a/Maple2.File.Parser/Xml/Skill/Basic.cs b/Maple2.File.Parser/Xml/Skill/Basic.cs index 050bab7..d0d36a7 100644 --- a/Maple2.File.Parser/Xml/Skill/Basic.cs +++ b/Maple2.File.Parser/Xml/Skill/Basic.cs @@ -8,3 +8,9 @@ public partial class Basic : IFeatureLocale { [XmlElement] public Kinds kinds; [XmlElement] public StateAttribute stateAttr; } + +public partial class BasicKR : IFeatureLocale { + [XmlElement] public UI ui; + [XmlElement] public KindsKR kinds; + [XmlElement] public StateAttribute stateAttr; +} diff --git a/Maple2.File.Parser/Xml/Skill/Kinds.cs b/Maple2.File.Parser/Xml/Skill/Kinds.cs index 17fea8d..f4070c5 100644 --- a/Maple2.File.Parser/Xml/Skill/Kinds.cs +++ b/Maple2.File.Parser/Xml/Skill/Kinds.cs @@ -34,3 +34,35 @@ public partial class Kinds { [XmlAttribute] public int emotionType; // 0,1,2 [XmlAttribute] public bool unrideOnHit; } + +public partial class KindsKR { + [XmlAttribute] public int type; // 0,1,2,3 + [XmlAttribute] public int subType; // 0,1,2,3,4,5,6,7,8,9 + [XmlAttribute] public int rangeType; // 0,1,2,3 + [XmlAttribute] public int groupType; // 0,2 + [XmlAttribute] public int jump; // SkillId + [XmlAttribute] public string state = string.Empty; // gos* + [XmlAttribute("continue")] public bool continueSkill; + [XmlAttribute] public bool spRecoverySkill; + [XmlAttribute] public int element; // 0,1,2,3,4,5,6,7 + [XmlAttribute] public int motionType; // 0 + [XmlAttribute] public string emotion = string.Empty; + [XmlAttribute] public float offsetNameTag; + [XmlAttribute] public float offsetHPBar; + [XmlAttribute] public int immediateActive; // 0,1,2 + [XmlAttribute] public bool weaponDependency; + [XmlAttribute] public bool unrideOnUse; + [XmlAttribute] public bool releaseObjectWeapon = true; + [XmlAttribute] public bool releaseStunState; + [XmlAttribute] public bool disableWater; + [XmlAttribute] public bool holdAttack; + [M2dArray] public int[] groupIDs = Array.Empty(); + + // Ignored by client. + [XmlAttribute] public int emotionNameTagOffset; // 0 + [XmlAttribute] public string changeSkillCheckEffectID = string.Empty; // int[] + [XmlAttribute] public string changeSkillCheckEffectLevel = string.Empty; // int[] + [XmlAttribute] public string changeSkillID = string.Empty; // int[] + [XmlAttribute] public int emotionType; // 0,1,2 + [XmlAttribute] public bool unrideOnHit; +} diff --git a/Maple2.File.Parser/Xml/Skill/Skill.cs b/Maple2.File.Parser/Xml/Skill/Skill.cs index 8f6cfda..ca95276 100644 --- a/Maple2.File.Parser/Xml/Skill/Skill.cs +++ b/Maple2.File.Parser/Xml/Skill/Skill.cs @@ -1,6 +1,8 @@ using System.Xml.Serialization; using M2dXmlGenerator; using Maple2.File.Parser.Xml.Skill.Property; +// ReSharper disable InconsistentNaming +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. namespace Maple2.File.Parser.Xml.Skill; @@ -134,3 +136,42 @@ public partial class SkillAttackData { // Ignored by client. [XmlAttribute] public string compulsionHit = string.Empty; } + + +// KR version: ./data/xml/skilldata/%04d.xml +[XmlRoot("ms2")] +public partial class SkillDataKR : IFeatureLocale { + [XmlElement("skill")] + public List Skills; +} + +public class SkillKR { + [XmlAttribute] + public int id; + + [XmlAttribute] + public int originId = 0; + + [XmlAttribute] + public string comment = string.Empty; + + [XmlElement("basic")] + public BasicKR basic; + + [XmlElement("level")] + public List levels; +} + +public class SkillLevelKR : SkillLevelData { + [XmlAttribute] + public int sp = 0; + + [XmlAttribute] + public int ep = 0; + + [XmlAttribute] + public int cooldown = 0; + + [XmlAttribute] + public string stringParam = string.Empty; +} diff --git a/Maple2.File.Parser/Xml/Table/DungeonRoom.cs b/Maple2.File.Parser/Xml/Table/DungeonRoom.cs index 07e46f7..46eadc5 100644 --- a/Maple2.File.Parser/Xml/Table/DungeonRoom.cs +++ b/Maple2.File.Parser/Xml/Table/DungeonRoom.cs @@ -15,7 +15,7 @@ public partial class DungeonRoom : IFeatureLocale { [XmlAttribute] public int dungeonRoomID; [XmlAttribute] public short dungeonLevel; [XmlAttribute] public DungeonPlayType playType; - [XmlAttribute] public DungeonGroupType groupType; + [M2dEnum] public DungeonGroupType groupType; [XmlAttribute] public int clearValue; [XmlAttribute] public DungeonCooldownType cooldownType; [XmlAttribute] public int cooldownValue; diff --git a/Maple2.File.Parser/Xml/Table/IndividualItemDrop.cs b/Maple2.File.Parser/Xml/Table/IndividualItemDrop.cs index f8c1477..edfcdda 100644 --- a/Maple2.File.Parser/Xml/Table/IndividualItemDrop.cs +++ b/Maple2.File.Parser/Xml/Table/IndividualItemDrop.cs @@ -63,3 +63,36 @@ public partial class IndividualItemDrop : IFeatureLocale { [M2dArray] public int[] dropCount = Array.Empty(); [M2dArray] public int[] dropCountProbability = Array.Empty(); } + +// ./data/xml/table/individualitemdrop_final.xml +[XmlRoot("ms2")] +public partial class IndividualItemDropRootKR { + [XmlElement("dropBox")] public List DropBoxes = []; +} + +public partial class IndividualItemDropBox : IFeatureLocale { + [XmlAttribute("dropBoxID")] public int DropBoxID; + + [XmlElement("group")] public List Groups = []; +} + +public partial class IndividualItemDropGroup : IFeatureLocale { + [XmlAttribute("dropGroupID")] public int DropGroupID; + + [XmlElement("v")] public List Items = []; +} + +public partial class IndividualItemDropItem : IFeatureLocale { + [XmlAttribute] public int enchantLevel; + [XmlAttribute] public int itemID; + [XmlAttribute] public int itemID2; + [XmlAttribute] public int itemLifeType; + [XmlAttribute] public int itemLifeValue; + [XmlAttribute] public float maxCount; + [XmlAttribute] public float minCount; + [XmlAttribute] public bool showIconOnGachaUI; + [XmlAttribute] public byte showTooltip; + [XmlAttribute] public int socketDataID; + [XmlAttribute] public bool tradableCountDeduction; + [XmlAttribute] public int uiItemRank; +} diff --git a/Maple2.File.Parser/Xml/Table/ItemMergeOption.cs b/Maple2.File.Parser/Xml/Table/ItemMergeOption.cs index 3afa601..85228df 100644 --- a/Maple2.File.Parser/Xml/Table/ItemMergeOption.cs +++ b/Maple2.File.Parser/Xml/Table/ItemMergeOption.cs @@ -65,3 +65,39 @@ public partial class Option { }; } } + + +// ./data/xml/table/itemmergeoptionbase.xml +[XmlRoot("ms2")] +public class ItemMergeOptionRootKR { + [XmlElement] public List mergeOption = []; +} + +public partial class MergeOptionKR : IFeatureLocale { + [XmlAttribute] public int id; + + [XmlElement] public List slot = []; +} + +public partial class Slot { + [XmlAttribute] public int part = 1; + [M2dArray] public int[] partLimit = []; + + [XmlElement] public List option = []; +} + +public partial class OptionKR { + [XmlAttribute] public string optionName = string.Empty; + [XmlAttribute] public int min; + + [XmlAttribute] public float idx0_max; + [XmlAttribute] public float idx1_max; + [XmlAttribute] public float idx2_max; + [XmlAttribute] public float idx3_max; + [XmlAttribute] public float idx4_max; + [XmlAttribute] public float idx5_max; + [XmlAttribute] public float idx6_max; + [XmlAttribute] public float idx7_max; + [XmlAttribute] public float idx8_max; + [XmlAttribute] public float idx9_max; +} diff --git a/Maple2.File.Parser/Xml/Table/JobTable.cs b/Maple2.File.Parser/Xml/Table/JobTable.cs index 1550c00..67e1838 100644 --- a/Maple2.File.Parser/Xml/Table/JobTable.cs +++ b/Maple2.File.Parser/Xml/Table/JobTable.cs @@ -66,3 +66,41 @@ public partial class LearnSkill : IFeatureLocale { [M2dArray] public int[] sub = Array.Empty(); } } + + +[XmlRoot("ms2")] +public partial class JobRootKR { + [M2dFeatureLocale(Selector = "jobGroupID")] private IList _job; +} + +public partial class JobTableKR : IFeatureLocale { + [XmlAttribute] public int jobGroupID = 1; + [XmlAttribute] public int subJob1 = 1; + [XmlAttribute] public int subJob2 = 1; + [XmlAttribute] public int characterBGM; + [XmlAttribute] public int defaultWeaponSlot; + [XmlAttribute] public int startField; // default = 524289? + [XmlAttribute] public string characterVoice = string.Empty; + + [M2dArray] public int[] startItems = Array.Empty(); + + [XmlElement("skills")] public SkillsKR skills; +} + +public partial class SkillsKR { + [XmlElement("v")] public List skills; + + public partial class Skill : IFeatureLocale { + [XmlAttribute] public int skillID; + [M2dArray] public int[] subSkillIDs = Array.Empty(); + [XmlAttribute] public int jobLevel; + [XmlAttribute] public short maxLevel = 1; + [XmlAttribute] public int quickSlotPriority; + [M2dArray] public int[] uiPosition = Array.Empty(); + [XmlAttribute] public bool uiHighlight; + [M2dArray] public int[] requireLevel = Array.Empty(); + [M2dArray] public int[] requireSkillIDs = Array.Empty(); + [M2dArray] public int[] requireSkillLevels = Array.Empty(); + [XmlAttribute] public int requireQuestID; + } +} diff --git a/Maple2.File.Parser/Xml/Table/SetItemOption.cs b/Maple2.File.Parser/Xml/Table/SetItemOption.cs index 89e5cd9..8a1b1b3 100644 --- a/Maple2.File.Parser/Xml/Table/SetItemOption.cs +++ b/Maple2.File.Parser/Xml/Table/SetItemOption.cs @@ -27,3 +27,29 @@ public partial class Part : ItemOption, IFeatureLocale { [XmlAttribute] public int sgi_boss_target; } } + +// ./data/xml/table/setiteminfo.xml +[XmlRoot("ms2")] +public partial class SetItemOptionRootKR { + [XmlElement("set")] public List option; +} + +public partial class SetItemOptionKR : IFeatureLocale { + [XmlAttribute] public int id; + [XmlAttribute] public int optionID; + [M2dArray] public int[] itemIDs = []; + + [XmlElement("part")] public List part; + + public partial class Part : ItemOptionKR, IFeatureLocale { + [XmlAttribute] public int count; + [M2dArray] public int[] additionalEffectID; + [M2dArray] public short[] additionalEffectLevel; + [XmlAttribute] public string animationPrefix; + [XmlAttribute] public string setEffect; + [XmlAttribute] public string groundAttribute; + + [XmlAttribute] public int sgi_target; + [XmlAttribute] public int sgi_boss_target; + } +} diff --git a/Maple2.File.Tests/AdditionalEffectParserTest.cs b/Maple2.File.Tests/AdditionalEffectParserTest.cs index 0be73eb..fd30f12 100644 --- a/Maple2.File.Tests/AdditionalEffectParserTest.cs +++ b/Maple2.File.Tests/AdditionalEffectParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.AdditionalEffect; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class AdditionalEffectParserTest { [TestMethod] public void TestAdditionalEffectParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new AdditionalEffectParser(TestUtils.XmlReader); int count = 0; @@ -18,4 +20,19 @@ public void TestAdditionalEffectParser() { } Assert.AreEqual(6079, count); } + + [TestMethod] + public void TestAdditionalEffectParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new AdditionalEffectParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, IList data) in parser.Parse()) { + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(6070, count); + } } + diff --git a/Maple2.File.Tests/AiParserTest.cs b/Maple2.File.Tests/AiParserTest.cs index c5b81f3..ac58670 100644 --- a/Maple2.File.Tests/AiParserTest.cs +++ b/Maple2.File.Tests/AiParserTest.cs @@ -121,3 +121,4 @@ public void TestAiParser() { Assert.IsTrue(foundAnyNodes); } } + diff --git a/Maple2.File.Tests/FunctionCubeParserTest.cs b/Maple2.File.Tests/FunctionCubeParserTest.cs index febced2..c1f6fbf 100644 --- a/Maple2.File.Tests/FunctionCubeParserTest.cs +++ b/Maple2.File.Tests/FunctionCubeParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Object; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,14 +9,33 @@ namespace Maple2.File.Tests; public class FunctionCubeParserTest { [TestMethod] public void TestFunctionCubeParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new FunctionCubeParser(TestUtils.XmlReader); // parser.FunctionCubeSerializer.UnknownElement += TestUtils.UnknownElementHandler; // parser.FunctionCubeSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + int count = 0; foreach ((int id, FunctionCubeRoot data) in parser.Parse()) { Assert.IsTrue(id >= 0); Assert.IsNotNull(data); + count++; } + Assert.AreEqual(427, count); + } + + [TestMethod] + public void TestFunctionCubeParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new FunctionCubeParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, FunctionCubeRoot data) in parser.Parse()) { + Assert.IsTrue(id >= 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(433, count); } } + diff --git a/Maple2.File.Tests/ItemOptionParserTest.cs b/Maple2.File.Tests/ItemOptionParserTest.cs index da45f5a..a3ed8b5 100644 --- a/Maple2.File.Tests/ItemOptionParserTest.cs +++ b/Maple2.File.Tests/ItemOptionParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Maple2.File.Tests; @@ -7,6 +8,7 @@ namespace Maple2.File.Tests; public class ItemOptionParserTest { [TestMethod] public void TestItemOptionParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ItemOptionParser(TestUtils.XmlReader); foreach (var data in parser.ParseConstant()) { @@ -22,6 +24,7 @@ public void TestItemOptionParser() { [TestMethod] public void TestItemMergeOptionParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ItemOptionParser(TestUtils.XmlReader); foreach (var data in parser.ParseMergeOptionBase()) { @@ -34,6 +37,7 @@ public void TestItemMergeOptionParser() { [TestMethod] public void TestItemOptionPickParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ItemOptionParser(TestUtils.XmlReader); foreach (var data in parser.ParsePick()) { @@ -43,6 +47,7 @@ public void TestItemOptionPickParser() { [TestMethod] public void TestItemOptionVariationParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ItemOptionParser(TestUtils.XmlReader); foreach (var data in parser.ParseVariation()) { @@ -52,4 +57,65 @@ public void TestItemOptionVariationParser() { Assert.IsNotNull(data.Option); } } + + [TestMethod] + public void TestItemOptionParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ItemOptionParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach (var data in parser.ParseConstantKr()) { + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(4013, count); + + count = 0; + foreach (var data in parser.ParseRandomKr()) { + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(500, count); + + // doesnt exist in kms2? + // foreach (var data in parser.ParseStatic()) { + // Assert.IsNotNull(data); + // } + } + + [TestMethod] + public void TestItemMergeOptionParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ItemOptionParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach (var data in parser.ParseMergeOptionBaseKr()) { + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(42, count); + } + + // [TestMethod] // Moved to constant + // public void TestItemOptionPickParserKR() { + // var parser = new ItemOptionParser(TestUtilsKR.XmlReader); + + // foreach (var data in parser.ParsePick()) { + // Assert.IsNotNull(data); + // } + // } + + [TestMethod] + public void TestItemOptionVariationParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ItemOptionParser(TestUtilsKr.XmlReader); + + foreach (var data in parser.ParseVariation()) { + Assert.IsNotNull(data); + } + foreach (var data in parser.ParseVariationEquip()) { + Assert.IsNotNull(data.Option); + } + } } + diff --git a/Maple2.File.Tests/ItemParserTest.cs b/Maple2.File.Tests/ItemParserTest.cs index e61ed11..06da821 100644 --- a/Maple2.File.Tests/ItemParserTest.cs +++ b/Maple2.File.Tests/ItemParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Item; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class ItemParserTest { [TestMethod] public void TestItemParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ItemParser(TestUtils.XmlReader); // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -15,10 +17,53 @@ public void TestItemParser() { // parser.ItemSerializer.UnknownElement += TestUtils.UnknownElementHandler; // parser.ItemSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; - foreach ((int id, string name, ItemData data) in parser.Parse()) { + int count = 0; + foreach ((int id, string name, ItemData data) in parser.Parse()) { // Debug.WriteLine($"Parsing item: {id} ({name})"); Assert.IsTrue(id > 0); Assert.IsNotNull(data); + + count++; + } + Assert.AreEqual(35309, count); + } + + [TestMethod] + public void TestItemParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ItemParser(TestUtilsKr.XmlReader); + + // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.NameSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + // parser.ItemSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.ItemSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + + int count = 0; + foreach ((int id, string name, ItemData data) in parser.Parse()) { + // Debug.WriteLine($"Parsing item: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; } + Assert.AreEqual(35970, count); + } + + [TestMethod] + public void TestItemNames() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + var parser = new ItemParser(TestUtils.XmlReader); + var itemNames = parser.ItemNames(); + + Assert.AreEqual(34038, itemNames.Count); + } + + [TestMethod] + public void TestItemNamesKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ItemParser(TestUtilsKr.XmlReader); + var itemNames = parser.ItemNames(); + + Assert.AreEqual(34273, itemNames.Count); } } + diff --git a/Maple2.File.Tests/MapParserTest.cs b/Maple2.File.Tests/MapParserTest.cs index 1d6e7ba..24c4670 100644 --- a/Maple2.File.Tests/MapParserTest.cs +++ b/Maple2.File.Tests/MapParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Map; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class MapParserTest { [TestMethod] public void TestMapParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new MapParser(TestUtils.XmlReader); // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -15,10 +17,52 @@ public void TestMapParser() { // parser.MapSerializer.UnknownElement += TestUtils.UnknownElementHandler; // parser.MapSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + int count = 0; foreach ((int id, string name, MapData data) in parser.Parse()) { // Debug.WriteLine($"Parsing Map: {id} ({name})"); Assert.IsTrue(id > 0); Assert.IsNotNull(data); + count++; } + Assert.AreEqual(1200, count); + } + + [TestMethod] + public void TestMapParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new MapParser(TestUtilsKr.XmlReader); + + // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.NameSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + // parser.MapSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.MapSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + + int count = 0; + foreach ((int id, string name, MapData data) in parser.Parse()) { + // Debug.WriteLine($"Parsing Map: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(1299, count); + } + + [TestMethod] + public void TestMapNames() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + var parser = new MapParser(TestUtils.XmlReader); + var mapNames = parser.ParseMapNames(); + + Assert.AreEqual(1152, mapNames.Count); + } + + [TestMethod] + public void TestMapNamesKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new MapParser(TestUtilsKr.XmlReader); + var mapNames = parser.ParseMapNames(); + + Assert.AreEqual(1282, mapNames.Count); } } + diff --git a/Maple2.File.Tests/NifParserTest.cs b/Maple2.File.Tests/NifParserTest.cs index b489887..a34cfba 100644 --- a/Maple2.File.Tests/NifParserTest.cs +++ b/Maple2.File.Tests/NifParserTest.cs @@ -21,7 +21,16 @@ public void TestLlidHash() { [TestMethod] public void TestNifParser() { var parser = new NifParser(TestUtils.ModelM2dReaders); + ValidateNifMeshData(parser); + } + [TestMethod] + public void TestNifParserKr() { + var parser = new NifParser(TestUtilsKr.ModelM2dReaders); + ValidateNifMeshData(parser); + } + + private static void ValidateNifMeshData(NifParser parser) { foreach ((uint llid, string relpath, NifDocument document) in parser.Parse()) { try { document.Parse(); @@ -172,3 +181,4 @@ public void TestMatrixParsing() { new Vector3(0, 0, 1)); } } + diff --git a/Maple2.File.Tests/NpcParserTest.cs b/Maple2.File.Tests/NpcParserTest.cs index 64c99a7..4732d65 100644 --- a/Maple2.File.Tests/NpcParserTest.cs +++ b/Maple2.File.Tests/NpcParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Npc; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class NpcParserTest { [TestMethod] public void TestNpcParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new NpcParser(TestUtils.XmlReader); // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -15,10 +17,64 @@ public void TestNpcParser() { // parser.NpcSerializer.UnknownElement += TestUtils.UnknownElementHandler; // parser.NpcSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + int count = 0; foreach ((int id, string name, NpcData data, List dummy) in parser.Parse()) { // Debug.WriteLine($"Parsing Npc: {id} ({name})"); Assert.IsTrue(id > 0); Assert.IsNotNull(data); + count++; } + Assert.AreEqual(7535, count); + } + + [TestMethod] + public void TestNpcParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new NpcParser(TestUtilsKr.XmlReader); + + // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.NameSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + // parser.NpcSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.NpcSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + + int count = 0; + foreach ((int id, string name, NpcDataKR data, List dummy) in parser.ParseKr()) { + // Debug.WriteLine($"Parsing Npc: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(10795, count); + } + + [TestMethod] + public void TestNpcNameParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + var parser = new NpcParser(TestUtils.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseNpcNames()) { + // Debug.WriteLine($"Parsing Npc Name: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(name); + count++; + } + Assert.AreEqual(7114, count); + } + + [TestMethod] + public void TestNpcNameParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new NpcParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseNpcNames()) { + // Debug.WriteLine($"Parsing Npc Name: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(name); + count++; + } + Assert.AreEqual(7850, count); } } + diff --git a/Maple2.File.Tests/QuestParserTest.cs b/Maple2.File.Tests/QuestParserTest.cs index 17d09b5..7cef7a5 100644 --- a/Maple2.File.Tests/QuestParserTest.cs +++ b/Maple2.File.Tests/QuestParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Quest; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class QuestParserTest { [TestMethod] public void TestQuestParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new QuestParser(TestUtils.XmlReader); // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -15,10 +17,64 @@ public void TestQuestParser() { // parser.QuestSerializer.UnknownElement += TestUtils.UnknownElementHandler; // parser.QuestSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + int count = 0; foreach ((int id, string name, QuestData data) in parser.Parse()) { // Debug.WriteLine($"Parsing Quest: {id} ({name})"); Assert.IsTrue(id > 0); Assert.IsNotNull(data); + count++; } + Assert.AreEqual(4903, count); + } + + [TestMethod] + public void TestQuestParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new QuestParser(TestUtilsKr.XmlReader); + + // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.NameSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + // parser.QuestSerializer.UnknownElement += TestUtils.UnknownElementHandler; + // parser.QuestSerializer.UnknownAttribute += TestUtils.UnknownAttributeHandler; + + int count = 0; + foreach ((int id, string name, QuestDataKR data) in parser.ParseKr()) { + // Debug.WriteLine($"Parsing Quest: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(6961, count); + } + + [TestMethod] + public void TestQuestDescriptionParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + var parser = new QuestParser(TestUtils.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseQuestDescriptions()) { + // Debug.WriteLine($"Parsing Quest Description: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(name); + count++; + } + Assert.AreEqual(5612, count); + } + + [TestMethod] + public void TestQuestDescriptionParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new QuestParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseQuestDescriptions()) { + // Debug.WriteLine($"Parsing Quest Description: {id} ({name})"); + Assert.IsTrue(id > 0); + Assert.IsNotNull(name); + count++; + } + Assert.AreEqual(5793, count); } } + diff --git a/Maple2.File.Tests/RidingParserTest.cs b/Maple2.File.Tests/RidingParserTest.cs index 3d243ef..ade75f2 100644 --- a/Maple2.File.Tests/RidingParserTest.cs +++ b/Maple2.File.Tests/RidingParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Riding; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class RidingParserTest { [TestMethod] public void TestRidingParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new RidingParser(TestUtils.XmlReader); int count = 0; @@ -22,6 +24,7 @@ public void TestRidingParser() { [TestMethod] public void TestRidingPassengerParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new RidingParser(TestUtils.XmlReader); int count = 0; @@ -33,4 +36,25 @@ public void TestRidingPassengerParser() { } Assert.AreEqual(29, count); } + + [TestMethod] + public void TestRidingParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new RidingParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, RidingKR data) in parser.ParseKr()) { + // Debug.WriteLine($"Parsing Riding: {id}"); + Assert.IsTrue(id >= 0); + Assert.IsNotNull(data); + if (data.passengers != null) { + foreach (PassengerRiding passenger in data.passengers) { + Assert.IsNotNull(passenger); + } + } + count++; + } + Assert.AreEqual(615, count); + } } + diff --git a/Maple2.File.Tests/ScriptParserTest.cs b/Maple2.File.Tests/ScriptParserTest.cs index 89be884..85529a2 100644 --- a/Maple2.File.Tests/ScriptParserTest.cs +++ b/Maple2.File.Tests/ScriptParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Script; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class ScriptParserTest { [TestMethod] public void TestNpcScriptParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ScriptParser(TestUtils.XmlReader); // parser.scriptStringSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -26,6 +28,7 @@ public void TestNpcScriptParser() { [TestMethod] public void TestQuestScriptParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ScriptParser(TestUtils.XmlReader); // parser.scriptStringSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -44,6 +47,7 @@ public void TestQuestScriptParser() { [TestMethod] public void TestStringsParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new ScriptParser(TestUtils.XmlReader); // parser.NameSerializer.UnknownElement += TestUtils.UnknownElementHandler; @@ -59,4 +63,34 @@ public void TestStringsParser() { } Assert.AreEqual(20124, count); } + + + [TestMethod] + public void TestNpcScriptParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ScriptParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, NpcScriptKR script) in parser.ParseNpcKr()) { + Assert.IsTrue(id > 0); + Assert.IsNotNull(script); + count++; + } + Assert.AreEqual(3271, count); + } + + [TestMethod] + public void TestQuestScriptParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new ScriptParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, QuestScript script) in parser.ParseQuestKr()) { + Assert.IsTrue(id > 0); + Assert.IsNotNull(script); + count++; + } + Assert.AreEqual(4291, count); + } } + diff --git a/Maple2.File.Tests/ServerTableParserTest.cs b/Maple2.File.Tests/ServerTableParserTest.cs index e878b01..543dc13 100644 --- a/Maple2.File.Tests/ServerTableParserTest.cs +++ b/Maple2.File.Tests/ServerTableParserTest.cs @@ -436,3 +436,4 @@ public void TestItemOptionRandom() { } } } + diff --git a/Maple2.File.Tests/SkillParserTest.cs b/Maple2.File.Tests/SkillParserTest.cs index db88adb..6024d8e 100644 --- a/Maple2.File.Tests/SkillParserTest.cs +++ b/Maple2.File.Tests/SkillParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Skill; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -8,6 +9,7 @@ namespace Maple2.File.Tests; public class SkillParserTest { [TestMethod] public void TestSkillParser() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); var parser = new SkillParser(TestUtils.XmlReader); int count = 0; @@ -18,4 +20,38 @@ public void TestSkillParser() { } Assert.AreEqual(9915, count); } + + [TestMethod] + public void TestSkillParserKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new SkillParser(TestUtilsKr.XmlReader); + + int count = 0; + foreach ((int id, string name, SkillKR data) in parser.ParseKr()) { + Assert.IsTrue(id > 0); + Assert.IsNotNull(data); + count++; + } + Assert.AreEqual(9433, count); + } + + + [TestMethod] + public void TestSkillNames() { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + var parser = new SkillParser(TestUtils.XmlReader); + Dictionary skillNames = parser.LoadSkillNames(); + + Assert.AreEqual(1392, skillNames.Count); + } + + [TestMethod] + public void TestSkillNamesKr() { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + var parser = new SkillParser(TestUtilsKr.XmlReader); + Dictionary skillNames = parser.LoadSkillNames(); + + Assert.AreEqual(1421, skillNames.Count); + } } + diff --git a/Maple2.File.Tests/TableParserKRTest.cs b/Maple2.File.Tests/TableParserKRTest.cs new file mode 100644 index 0000000..ff567f2 --- /dev/null +++ b/Maple2.File.Tests/TableParserKRTest.cs @@ -0,0 +1,653 @@ +using Maple2.File.Parser; +using Maple2.File.Parser.Tools; +using Maple2.File.Parser.Xml.Table; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Maple2.File.Tests; + +[TestClass] +public class TableParserKrTest { + private static TableParser _parser = null!; + + [ClassInitialize] + public static void ClassInit(TestContext context) { + Filter.Load(TestUtilsKr.XmlReader, "KR", "Live"); + _parser = new TableParser(TestUtilsKr.XmlReader); + } + + [TestMethod] + public void TestColorPaletteParserKr() { + foreach ((_, _) in _parser.ParseColorPalette()) { + continue; + } + } + + [TestMethod] + public void TestParseScrollKr() { + foreach ((_, _) in _parser.ParseEnchantScroll()) { + continue; + } + foreach ((_, _) in _parser.ParseItemRemakeScroll()) { + continue; + } + foreach ((_, _) in _parser.ParseItemRepackingScroll()) { + continue; + } + foreach ((_, _) in _parser.ParseItemSocketScroll()) { + continue; + } + } + + [TestMethod] + public void TestBankTypeKr() { + foreach ((_, _) in _parser.ParseBankType()) { + continue; + } + } + + [TestMethod] + public void TestChatStickerKr() { + foreach ((_, _) in _parser.ParseChatSticker()) { + continue; + } + } + + [TestMethod] + public void TestParseDefaultItemsKr() { + foreach ((_, _, _) in _parser.ParseDefaultItems()) { + continue; + } + } + + [TestMethod] + public void TestParseDungeonRoomKr() { + foreach ((_, _) in _parser.ParseDungeonRoom()) { + continue; + } + } + + [TestMethod] + public void TestDungeonRoundDataKr() { + foreach ((_, _) in _parser.ParseDungeonRoundData()) { + continue; + } + } + + [TestMethod] + public void TestDungeonRankRewardKr() { + foreach ((_, _) in _parser.ParseDungeonRankReward()) { + continue; + } + } + + [TestMethod] + public void TestDungeonMissionKr() { + foreach ((_, _) in _parser.ParseDungeonMission()) { + continue; + } + } + + [TestMethod] + public void TestDungeonConfigKr() { + foreach (var _ in _parser.ParseDungeonConfig()) { + continue; + } + } + + [TestMethod] + public void TestReverseRaidConfigKr() { + foreach (var _ in _parser.ParseReverseRaidConfig()) { + continue; + } + } + + [TestMethod] + public void TestUnitedWeeklyRewardKr() { + foreach (var _ in _parser.ParseUnitedWeeklyReward()) { + continue; + } + } + + [TestMethod] + public void TestFishKr() { + foreach ((_, _, _) in _parser.ParseFish()) { + continue; + } + } + + [TestMethod] + public void TestFishHabitatKr() { + foreach ((_, _) in _parser.ParseFishHabitat()) { + continue; + } + } + + [TestMethod] + public void TestFishingRodKr() { + foreach ((_, _) in _parser.ParseFishingRod()) { + continue; + } + } + + [TestMethod] + public void TestFishingSpotKr() { + foreach ((_, _) in _parser.ParseFishingSpot()) { + continue; + } + } + + [TestMethod] + public void TestGuildBuffKr() { + foreach ((_, _) in _parser.ParseGuildBuff()) { + continue; + } + } + + [TestMethod] + public void TestGuildContributionKr() { + foreach ((_, _) in _parser.ParseGuildContribution()) { + continue; + } + } + + [TestMethod] + public void TestGuildEventKr() { + foreach ((_, _) in _parser.ParseGuildEvent()) { + continue; + } + } + + [Ignore] // Removed from KMS2? + public void TestGuildExpKr() { + foreach ((_, _) in _parser.ParseGuildExp()) { + continue; + } + } + + [TestMethod] + public void TestGuildHouseKr() { + foreach ((_, _) in _parser.ParseGuildHouse()) { + continue; + } + } + + [TestMethod] + public void TestGuildNpcKr() { + foreach ((_, _) in _parser.ParseGuildNpc()) { + continue; + } + } + + [TestMethod] + public void TestGuildPropertyKr() { + foreach ((_, _) in _parser.ParseGuildProperty()) { + continue; + } + } + + [TestMethod] + public void TestParseInstrumentCategoryInfoKr() { + foreach ((_, _) in _parser.ParseInstrumentCategoryInfo()) { + continue; + } + } + + [TestMethod] + public void TestParseInstrumentInfoKr() { + foreach ((_, _) in _parser.ParseInstrumentInfo()) { + continue; + } + } + + [TestMethod] + public void TestParseInteractObjectInfoKr() { + foreach ((_, _, _) in _parser.ParseInteractObject()) { + continue; + } + foreach ((_, _) in _parser.ParseInteractObjectMastery()) { + continue; + } + } + + [TestMethod] + public void TestParseItemBreakIngredientKr() { + foreach ((_, _) in _parser.ParseItemBreakIngredient()) { + continue; + } + } + + [TestMethod] + public void TestParseItemExchangeScrollKr() { + foreach ((_, _) in _parser.ParseItemExchangeScroll()) { + continue; + } + } + + [TestMethod] + public void TestItemExtractionKr() { + foreach ((_, _) in _parser.ParseItemExtraction()) { + continue; + } + } + + [TestMethod] + public void TestParseItemGemstoneUpgradeKr() { + foreach ((_, _) in _parser.ParseItemGemstoneUpgrade()) { + continue; + } + } + + [TestMethod] + public void TestParseItemLapenshardUpgradeKr() { + foreach ((_, _) in _parser.ParseItemLapenshardUpgrade()) { + continue; + } + } + + [TestMethod] + public void TestParseItemSocketKr() { + foreach ((_, _) in _parser.ParseItemSocket()) { + continue; + } + } + + [TestMethod] + public void TestParseJobTableKr() { + Dictionary> results = _parser.ParseJobTableKR() + .GroupBy(result => result.jobGroupID) + .ToDictionary(group => group.Key, group => group.ToList()); + + var expected = new Dictionary { + {1, ("", 1)}, + {10, ("", 2)}, + {20, ("", 1)}, + {30, ("", 1)}, + {40, ("", 2)}, + {50, ("", 1)}, + {60, ("", 1)}, + {70, ("", 2)}, + {80, ("", 2)}, + {90, ("", 1)}, + {100, ("", 1)}, + {110, ("", 1)}, + }; + foreach ((int jobCode, (string feature, int itemCount)) in expected) { + Assert.IsTrue(results.TryGetValue(jobCode, out List? job)); + Assert.IsNotNull(job); + // Ensure that FeatureLocale was filtered properly + Assert.AreEqual(1, job.Count); + Assert.AreEqual(job[0].Feature, feature); + // Ensure that some value was parsed + Assert.IsTrue(job[0].skills.skills.Count > 0); + // Assert.IsTrue(job[0].learn.Count > 0); + // // Ensure the right amount of items are parsed + // Assert.AreEqual(job[0].startInvenItem.item.Count, itemCount); + // Assert.AreEqual(job[0].reward.item.Count, itemCount); + } + } + + [TestMethod] + public void TestParseMagicPathKr() { + foreach ((_, _) in _parser.ParseMagicPath()) { + continue; + } + } + + [TestMethod] + public void TestParseMapSpawnTagKr() { + foreach ((_, _) in _parser.ParseMapSpawnTag()) { + continue; + } + } + + [TestMethod] + public void TestMasteryRecipeKr() { + foreach ((_, _) in _parser.ParseMasteryRecipe()) { + continue; + } + } + + [TestMethod] + public void TestMasteryRewardKr() { + foreach ((_, _) in _parser.ParseMasteryReward()) { + continue; + } + } + + [TestMethod] + public void TestParsePetTableKr() { + foreach ((_, _) in _parser.ParsePetExp()) { + continue; + } + foreach ((_, _) in _parser.ParsePetProperty()) { + continue; + } + foreach ((_, _) in _parser.ParsePetSpawnInfo()) { + continue; + } + } + + [TestMethod] + public void TestParsePremiumClubEffectKr() { + foreach ((_, _) in _parser.ParsePremiumClubEffect()) { + continue; + } + } + + [TestMethod] + public void TestParsePremiumClubItemKr() { + foreach ((_, _) in _parser.ParsePremiumClubItem()) { + continue; + } + } + + [TestMethod] + public void TestParsePremiumClubPackageKr() { + foreach ((_, _) in _parser.ParsePremiumClubPackage()) { + continue; + } + } + + [TestMethod] + public void TestParseSetItemInfoKr() { + foreach ((_, _, _) in _parser.ParseSetItemInfo()) { + continue; + } + } + + [TestMethod] + public void TestParseSetItemOptionKr() { + int count = 0; + foreach (var (Id, option) in _parser.ParseSetItemOptionKR()) { + if (Id == 15123101) { + Assert.AreEqual(2, option.part[0].count); + Assert.AreEqual(9, option.part[0].str_value_base); + Assert.AreEqual(4, option.part[1].count); + Assert.AreEqual(6, option.part[1].pap_value_base); + Assert.AreEqual(5, option.part[2].count); + Assert.AreEqual(20, option.part[2].pen_rate_base); + } + count++; + } + Assert.AreEqual(1039, count); + } + + [TestMethod] + public void TestParseTitleTagKr() { + foreach ((_, _, _) in _parser.ParseTitleTag()) { + continue; + } + } + + [TestMethod] + public void TestIndividualItemDropKr() { + int count = 0; + foreach ((_, _) in _parser.ParseIndividualItemDropKR()) { + count++; + } + Assert.AreEqual(4625, count); + } + + [TestMethod] + public void TestGachaInfoKr() { + foreach ((_, _) in _parser.ParseGachaInfo()) { + continue; + } + } + + [TestMethod] + public void TestShopBeautyCouponKr() { + foreach ((_, _) in _parser.ParseShopBeautyCoupon()) { + continue; + } + } + + [TestMethod] + public void TestShopFurnishingUgcAllKr() { + foreach ((_, _) in _parser.ParseFurnishingShopUgcAll()) { + continue; + } + } + + [TestMethod] + public void TestShopFurnishingMaidKr() { + foreach ((_, _) in _parser.ParseFurnishingShopMaid()) { + continue; + } + } + + [TestMethod] + public void TestMeretMarketCategoryKr() { + foreach ((_, _) in _parser.ParseMeretMarketCategory()) { + continue; + } + } + + [TestMethod] + public void TestExpBaseTableKr() { + foreach ((_, _) in _parser.ParseExpBaseTable()) { + continue; + } + } + + [TestMethod] + public void TestNextExpKr() { + foreach ((_, _) in _parser.ParseNextExp()) { + continue; + } + } + + [TestMethod] + public void TestAdventureLevelAbilityKr() { + foreach ((_, _) in _parser.ParseAdventureLevelAbility()) { + continue; + } + } + + [TestMethod] + public void TestAdventureLevelMissionKr() { + foreach ((_, _) in _parser.ParseAdventureLevelMission()) { + continue; + } + } + + [TestMethod] + public void TestAdventureLevelRewardKr() { + foreach ((_, _) in _parser.ParseAdventureLevelReward()) { + continue; + } + } + + [TestMethod] + public void TestUgcDesignKr() { + foreach ((_, _) in _parser.ParseUgcDesign()) { + continue; + } + } + + [TestMethod] + public void TestMasteryUgcHousingKr() { + foreach ((_, _) in _parser.ParseMasteryUgcHousing()) { + continue; + } + } + + [TestMethod] + public void TestUgcHousingPointRewardKr() { + foreach ((_, _) in _parser.ParseUgcHousingPointReward()) { + continue; + } + } + + [TestMethod] + public void TestBannerKr() { + foreach ((_, _) in _parser.ParseBanner()) { + continue; + } + } + + [TestMethod] + public void TestNameTagSymbolKr() { + foreach ((_, _) in _parser.ParseNameTagSymbol()) { + continue; + } + } + + [TestMethod] + public void TestCommonExpKr() { + foreach ((_, _) in _parser.ParseCommonExp()) { + continue; + } + } + + [TestMethod] + public void TestChapterBookKr() { + foreach ((_, _) in _parser.ParseChapterBook()) { + continue; + } + } + + [TestMethod] + public void TestLearningQuestKr() { + foreach ((_, _) in _parser.ParseLearningQuest()) { + continue; + } + } + + [TestMethod] + public void TestMasteryDifferentialFactorKr() { + foreach ((_, _) in _parser.ParseMasteryDifferentialFactor()) { + continue; + } + } + + [TestMethod] + public void TestRewardContentKr() { + foreach ((_, _) in _parser.ParseRewardContent()) { + continue; + } + } + + [TestMethod] + public void TestRewardContentItemKr() { + foreach ((_, _) in _parser.ParseRewardContentItem()) { + continue; + } + } + + [TestMethod] + public void TestRewardContentExpStaticKr() { + foreach ((_, _) in _parser.ParseRewardContentExpStatic()) { + continue; + } + } + + [TestMethod] + public void TestRewardContentMesoKr() { + foreach ((_, _) in _parser.ParseRewardContentMeso()) { + continue; + } + } + + [TestMethod] + public void TestRewardContentMesoStaticKr() { + foreach ((_, _) in _parser.ParseRewardContentMesoStatic()) { + continue; + } + } + + [Ignore] // Removed from KMS2 + public void TestSurvivalLevelKr() { + foreach ((_, _) in _parser.ParseSurvivalLevel()) { + continue; + } + } + + [Ignore] // Removed from KMS2 + public void TestSurvivalLevelRewardKr() { + foreach ((_, _) in _parser.ParseSurvivalLevelReward()) { + continue; + } + } + + [TestMethod] + public void TestBlackMarketStatTableKr() { + foreach ((_, _) in _parser.ParseBlackMarketStatTable()) { + continue; + } + } + + [TestMethod] + public void TestBlackMarketOptionKr() { + (_, _) = _parser.ParseBlackMarketOption(); + } + + [TestMethod] + public void TestBlackMarketCategoryKr() { + (_, _) = _parser.ParseBlackMarketCategory(); + } + + [TestMethod] + public void TestChangeJobKr() { + foreach ((_, _) in _parser.ParseChangeJob()) { + continue; + } + } + + [TestMethod] + public void TestFieldMissionKr() { + foreach ((_, _) in _parser.ParseFieldMission()) { + continue; + } + } + + [TestMethod] + public void TestWorldMapKr() { + foreach ((_, _) in _parser.ParseWorldMap()) { + continue; + } + } + + [Ignore] // Removed from KMS2 + public void TestMapleSurvivalSkinInfoKr() { + foreach ((_, _) in _parser.ParseMapleSurvivalSkinInfo()) { + continue; + } + } + + [TestMethod] + public void TestWeddingExpKr() { + foreach ((_, _) in _parser.ParseWeddingExp()) { + continue; + } + } + + [TestMethod] + public void TestWeddingPackageKr() { + foreach ((_, _) in _parser.ParseWeddingPackage()) { + continue; + } + } + + [TestMethod] + public void TestWeddingSkillKr() { + foreach ((_, _) in _parser.ParseWeddingSkill()) { + continue; + } + } + + [TestMethod] + public void TestWeddingRewardKr() { + foreach ((_, _) in _parser.ParseWeddingReward()) { + continue; + } + } + + [TestMethod] + public void TestSmartPushKr() { + foreach ((_, _) in _parser.ParseSmartPush()) { + continue; + } + } +} + diff --git a/Maple2.File.Tests/TableParserTest.cs b/Maple2.File.Tests/TableParserTest.cs index e15fa34..c2d18b2 100644 --- a/Maple2.File.Tests/TableParserTest.cs +++ b/Maple2.File.Tests/TableParserTest.cs @@ -1,4 +1,5 @@ using Maple2.File.Parser; +using Maple2.File.Parser.Tools; using Maple2.File.Parser.Xml.Table; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -6,315 +7,258 @@ namespace Maple2.File.Tests; [TestClass] public class TableParserTest { + private static TableParser _parser = null!; + + [ClassInitialize] + public static void ClassInit(TestContext context) { + Filter.Load(TestUtils.XmlReader, "NA", "Live"); + _parser = new TableParser(TestUtils.XmlReader); + } + + [TestMethod] public void TestColorPaletteParser() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseColorPalette()) { + foreach ((_, _) in _parser.ParseColorPalette()) { continue; } - foreach ((_, _) in parser.ParseColorPaletteAchieve()) { + foreach ((_, _) in _parser.ParseColorPaletteAchieve()) { continue; } } [TestMethod] public void TestParseScroll() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseEnchantScroll()) { + foreach ((_, _) in _parser.ParseEnchantScroll()) { continue; } - foreach ((_, _) in parser.ParseItemRemakeScroll()) { + foreach ((_, _) in _parser.ParseItemRemakeScroll()) { continue; } - foreach ((_, _) in parser.ParseItemRepackingScroll()) { + foreach ((_, _) in _parser.ParseItemRepackingScroll()) { continue; } - foreach ((_, _) in parser.ParseItemSocketScroll()) { + foreach ((_, _) in _parser.ParseItemSocketScroll()) { continue; } } [TestMethod] public void TestBankType() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseBankType()) { + foreach ((_, _) in _parser.ParseBankType()) { continue; } } [TestMethod] public void TestChatSticker() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseChatSticker()) { + foreach ((_, _) in _parser.ParseChatSticker()) { continue; } } [TestMethod] public void TestParseDefaultItems() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _, _) in parser.ParseDefaultItems()) { + foreach ((_, _, _) in _parser.ParseDefaultItems()) { continue; } } [TestMethod] public void TestParseDungeonRoom() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseDungeonRoom()) { + foreach ((_, _) in _parser.ParseDungeonRoom()) { continue; } } [TestMethod] public void TestDungeonRoundData() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseDungeonRoundData()) { + foreach ((_, _) in _parser.ParseDungeonRoundData()) { continue; } } [TestMethod] public void TestDungeonRankReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseDungeonRankReward()) { + foreach ((_, _) in _parser.ParseDungeonRankReward()) { continue; } } [TestMethod] public void TestDungeonMission() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseDungeonMission()) { + foreach ((_, _) in _parser.ParseDungeonMission()) { continue; } } [TestMethod] public void TestDungeonConfig() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach (var _ in parser.ParseDungeonConfig()) { + foreach (var _ in _parser.ParseDungeonConfig()) { continue; } } [TestMethod] public void TestReverseRaidConfig() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach (var _ in parser.ParseReverseRaidConfig()) { + foreach (var _ in _parser.ParseReverseRaidConfig()) { continue; } } [TestMethod] public void TestUnitedWeeklyReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach (var _ in parser.ParseUnitedWeeklyReward()) { + foreach (var _ in _parser.ParseUnitedWeeklyReward()) { continue; } } [TestMethod] public void TestFish() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _, _) in parser.ParseFish()) { + foreach ((_, _, _) in _parser.ParseFish()) { continue; } } [TestMethod] public void TestFishHabitat() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFishHabitat()) { + foreach ((_, _) in _parser.ParseFishHabitat()) { continue; } } [TestMethod] public void TestFishingRod() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFishingRod()) { + foreach ((_, _) in _parser.ParseFishingRod()) { continue; } } [TestMethod] public void TestFishingSpot() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFishingSpot()) { + foreach ((_, _) in _parser.ParseFishingSpot()) { continue; } } [TestMethod] public void TestGuildBuff() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildBuff()) { + foreach ((_, _) in _parser.ParseGuildBuff()) { continue; } } [TestMethod] public void TestGuildContribution() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildContribution()) { + foreach ((_, _) in _parser.ParseGuildContribution()) { continue; } } [TestMethod] public void TestGuildEvent() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildEvent()) { + foreach ((_, _) in _parser.ParseGuildEvent()) { continue; } } [TestMethod] public void TestGuildExp() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildEvent()) { + foreach ((_, _) in _parser.ParseGuildEvent()) { continue; } } [TestMethod] public void TestGuildHouse() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildHouse()) { + foreach ((_, _) in _parser.ParseGuildHouse()) { continue; } } [TestMethod] public void TestGuildNpc() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildNpc()) { + foreach ((_, _) in _parser.ParseGuildNpc()) { continue; } } [TestMethod] public void TestGuildProperty() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGuildProperty()) { + foreach ((_, _) in _parser.ParseGuildProperty()) { continue; } } [TestMethod] public void TestParseInstrumentCategoryInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseInstrumentCategoryInfo()) { + foreach ((_, _) in _parser.ParseInstrumentCategoryInfo()) { continue; } } [TestMethod] public void TestParseInstrumentInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseInstrumentInfo()) { + foreach ((_, _) in _parser.ParseInstrumentInfo()) { continue; } } [TestMethod] public void TestParseInteractObjectInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _, _) in parser.ParseInteractObject()) { + foreach ((_, _, _) in _parser.ParseInteractObject()) { continue; } - foreach ((_, _) in parser.ParseInteractObjectMastery()) { + foreach ((_, _) in _parser.ParseInteractObjectMastery()) { continue; } } [TestMethod] public void TestParseItemBreakIngredient() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemBreakIngredient()) { + foreach ((_, _) in _parser.ParseItemBreakIngredient()) { continue; } } [TestMethod] public void TestParseItemExchangeScroll() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemExchangeScroll()) { + foreach ((_, _) in _parser.ParseItemExchangeScroll()) { continue; } } [TestMethod] public void TestItemExtraction() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemExtraction()) { + foreach ((_, _) in _parser.ParseItemExtraction()) { continue; } } [TestMethod] public void TestParseItemGemstoneUpgrade() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemGemstoneUpgrade()) { + foreach ((_, _) in _parser.ParseItemGemstoneUpgrade()) { continue; } } [TestMethod] public void TestParseItemLapenshardUpgrade() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemLapenshardUpgrade()) { + foreach ((_, _) in _parser.ParseItemLapenshardUpgrade()) { continue; } } [TestMethod] public void TestParseItemSocket() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseItemSocket()) { + foreach ((_, _) in _parser.ParseItemSocket()) { continue; } } [TestMethod] public void TestParseJobTable() { - var parser = new TableParser(TestUtils.XmlReader); - - Dictionary> results = parser.ParseJobTable() + Dictionary> results = _parser.ParseJobTable() .GroupBy(result => result.code) .ToDictionary(group => group.Key, group => group.ToList()); @@ -349,490 +293,390 @@ public void TestParseJobTable() { [TestMethod] public void TestParseMagicPath() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMagicPath()) { + foreach ((_, _) in _parser.ParseMagicPath()) { continue; } } [TestMethod] public void TestParseMapSpawnTag() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMapSpawnTag()) { + foreach ((_, _) in _parser.ParseMapSpawnTag()) { continue; } } [TestMethod] public void TestMasteryRecipe() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMasteryRecipe()) { + foreach ((_, _) in _parser.ParseMasteryRecipe()) { continue; } } [TestMethod] public void TestMasteryReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMasteryReward()) { + foreach ((_, _) in _parser.ParseMasteryReward()) { continue; } } [TestMethod] public void TestParsePetTable() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParsePetExp()) { + foreach ((_, _) in _parser.ParsePetExp()) { continue; } - foreach ((_, _) in parser.ParsePetProperty()) { + foreach ((_, _) in _parser.ParsePetProperty()) { continue; } - foreach ((_, _) in parser.ParsePetSpawnInfo()) { + foreach ((_, _) in _parser.ParsePetSpawnInfo()) { continue; } } [TestMethod] public void TestParsePremiumClubEffect() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParsePremiumClubEffect()) { + foreach ((_, _) in _parser.ParsePremiumClubEffect()) { continue; } } [TestMethod] public void TestParsePremiumClubItem() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParsePremiumClubItem()) { + foreach ((_, _) in _parser.ParsePremiumClubItem()) { continue; } } [TestMethod] public void TestParsePremiumClubPackage() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParsePremiumClubPackage()) { + foreach ((_, _) in _parser.ParsePremiumClubPackage()) { continue; } } [TestMethod] public void TestParseSetItemInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _, _) in parser.ParseSetItemInfo()) { + foreach ((_, _, _) in _parser.ParseSetItemInfo()) { continue; } } [TestMethod] public void TestParseSetItemOption() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseSetItemOption()) { + foreach ((_, _) in _parser.ParseSetItemOption()) { continue; } } [TestMethod] public void TestParseTitleTag() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _, _) in parser.ParseTitleTag()) { + foreach ((_, _, _) in _parser.ParseTitleTag()) { continue; } } [TestMethod] public void TestIndividualItemDrop() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseIndividualItemDrop()) { + foreach ((_, _) in _parser.ParseIndividualItemDrop()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropCharge()) { + foreach ((_, _) in _parser.ParseIndividualItemDropCharge()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropEvent()) { + foreach ((_, _) in _parser.ParseIndividualItemDropEvent()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropEventNpc()) { + foreach ((_, _) in _parser.ParseIndividualItemDropEventNpc()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropNewGacha()) { + foreach ((_, _) in _parser.ParseIndividualItemDropNewGacha()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropPet()) { + foreach ((_, _) in _parser.ParseIndividualItemDropPet()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropQuestObj()) { + foreach ((_, _) in _parser.ParseIndividualItemDropQuestObj()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropQuestMob()) { + foreach ((_, _) in _parser.ParseIndividualItemDropQuestMob()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemDropGacha()) { + foreach ((_, _) in _parser.ParseIndividualItemDropGacha()) { continue; } - foreach ((_, _) in parser.ParseIndividualItemGearBox()) { + foreach ((_, _) in _parser.ParseIndividualItemGearBox()) { continue; } } [TestMethod] public void TestGachaInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseGachaInfo()) { + foreach ((_, _) in _parser.ParseGachaInfo()) { continue; } } [TestMethod] public void TestShopBeautyCoupon() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseShopBeautyCoupon()) { + foreach ((_, _) in _parser.ParseShopBeautyCoupon()) { continue; } } [TestMethod] public void TestShopFurnishingUgcAll() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFurnishingShopUgcAll()) { + foreach ((_, _) in _parser.ParseFurnishingShopUgcAll()) { continue; } } [TestMethod] public void TestShopFurnishingMaid() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFurnishingShopMaid()) { + foreach ((_, _) in _parser.ParseFurnishingShopMaid()) { continue; } } [TestMethod] public void TestMeretMarketCategory() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMeretMarketCategory()) { + foreach ((_, _) in _parser.ParseMeretMarketCategory()) { continue; } } [TestMethod] public void TestExpBaseTable() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseExpBaseTable()) { + foreach ((_, _) in _parser.ParseExpBaseTable()) { continue; } } [TestMethod] public void TestNextExp() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseNextExp()) { + foreach ((_, _) in _parser.ParseNextExp()) { continue; } } [TestMethod] public void TestAdventureLevelAbility() { - var parser = new TableParser(TestUtils.XmlReader); - var results = parser.ParseAdventureLevelAbility(); - - foreach ((_, _) in parser.ParseAdventureLevelAbility()) { + foreach ((_, _) in _parser.ParseAdventureLevelAbility()) { continue; } } [TestMethod] public void TestAdventureLevelMission() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseAdventureLevelMission()) { + foreach ((_, _) in _parser.ParseAdventureLevelMission()) { continue; } } [TestMethod] public void TestAdventureLevelReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseAdventureLevelReward()) { + foreach ((_, _) in _parser.ParseAdventureLevelReward()) { continue; } } [TestMethod] public void TestUgcDesign() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseUgcDesign()) { + foreach ((_, _) in _parser.ParseUgcDesign()) { continue; } } [TestMethod] public void TestMasteryUgcHousing() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMasteryUgcHousing()) { + foreach ((_, _) in _parser.ParseMasteryUgcHousing()) { continue; } } [TestMethod] public void TestUgcHousingPointReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseUgcHousingPointReward()) { + foreach ((_, _) in _parser.ParseUgcHousingPointReward()) { continue; } } [TestMethod] public void TestBanner() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseBanner()) { + foreach ((_, _) in _parser.ParseBanner()) { continue; } } [TestMethod] public void TestNameTagSymbol() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseNameTagSymbol()) { + foreach ((_, _) in _parser.ParseNameTagSymbol()) { continue; } } [TestMethod] public void TestCommonExp() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseCommonExp()) { + foreach ((_, _) in _parser.ParseCommonExp()) { continue; } } [TestMethod] public void TestChapterBook() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseChapterBook()) { + foreach ((_, _) in _parser.ParseChapterBook()) { continue; } } [TestMethod] public void TestLearningQuest() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseLearningQuest()) { + foreach ((_, _) in _parser.ParseLearningQuest()) { continue; } } [TestMethod] public void TestMasteryDifferentialFactor() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMasteryDifferentialFactor()) { + foreach ((_, _) in _parser.ParseMasteryDifferentialFactor()) { continue; } } [TestMethod] public void TestRewardContent() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseRewardContent()) { + foreach ((_, _) in _parser.ParseRewardContent()) { continue; } } [TestMethod] public void TestRewardContentItem() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseRewardContentItem()) { + foreach ((_, _) in _parser.ParseRewardContentItem()) { continue; } } [TestMethod] public void TestRewardContentExpStatic() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseRewardContentExpStatic()) { + foreach ((_, _) in _parser.ParseRewardContentExpStatic()) { continue; } } [TestMethod] public void TestRewardContentMeso() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseRewardContentMeso()) { + foreach ((_, _) in _parser.ParseRewardContentMeso()) { continue; } } [TestMethod] public void TestRewardContentMesoStatic() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseRewardContentMesoStatic()) { + foreach ((_, _) in _parser.ParseRewardContentMesoStatic()) { continue; } } [TestMethod] public void TestSurvivalLevel() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseSurvivalLevel()) { + foreach ((_, _) in _parser.ParseSurvivalLevel()) { continue; } } [TestMethod] public void TestSurvivalLevelReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseSurvivalLevelReward()) { + foreach ((_, _) in _parser.ParseSurvivalLevelReward()) { continue; } } [TestMethod] public void TestBlackMarketStatTable() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseBlackMarketStatTable()) { + foreach ((_, _) in _parser.ParseBlackMarketStatTable()) { continue; } } [TestMethod] public void TestBlackMarketOption() { - var parser = new TableParser(TestUtils.XmlReader); - - (_, _) = parser.ParseBlackMarketOption(); + (_, _) = _parser.ParseBlackMarketOption(); } [TestMethod] public void TestBlackMarketCategory() { - var parser = new TableParser(TestUtils.XmlReader); - - (_, _) = parser.ParseBlackMarketCategory(); + (_, _) = _parser.ParseBlackMarketCategory(); } [TestMethod] public void TestChangeJob() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseChangeJob()) { + foreach ((_, _) in _parser.ParseChangeJob()) { continue; } } [TestMethod] public void TestFieldMission() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseFieldMission()) { + foreach ((_, _) in _parser.ParseFieldMission()) { continue; } } [TestMethod] public void TestWorldMap() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseWorldMap()) { + foreach ((_, _) in _parser.ParseWorldMap()) { continue; } } [TestMethod] public void TestMapleSurvivalSkinInfo() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseMapleSurvivalSkinInfo()) { + foreach ((_, _) in _parser.ParseMapleSurvivalSkinInfo()) { continue; } } [TestMethod] public void TestWeddingExp() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseWeddingExp()) { + foreach ((_, _) in _parser.ParseWeddingExp()) { continue; } } [TestMethod] public void TestWeddingPackage() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseWeddingPackage()) { + foreach ((_, _) in _parser.ParseWeddingPackage()) { continue; } } [TestMethod] public void TestWeddingSkill() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseWeddingSkill()) { + foreach ((_, _) in _parser.ParseWeddingSkill()) { continue; } } [TestMethod] public void TestWeddingReward() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseWeddingReward()) { + foreach ((_, _) in _parser.ParseWeddingReward()) { continue; } } [TestMethod] public void TestSmartPush() { - var parser = new TableParser(TestUtils.XmlReader); - - foreach ((_, _) in parser.ParseSmartPush()) { + foreach ((_, _) in _parser.ParseSmartPush()) { continue; } } } + diff --git a/Maple2.File.Tests/TestUtils.cs b/Maple2.File.Tests/TestUtils.cs index e521455..310907e 100644 --- a/Maple2.File.Tests/TestUtils.cs +++ b/Maple2.File.Tests/TestUtils.cs @@ -24,7 +24,6 @@ static TestUtils() { } XmlReader = new M2dReader(@$"{m2dPath}\Xml.m2d"); - Filter.Load(XmlReader, "NA", "Live"); ExportedReader = new M2dReader(@$"{m2dPath}\Resource\Exported.m2d"); ServerReader = new M2dReader(@$"{m2dPath}\Server.m2d"); AssetMetadataReader = new M2dReader(@$"{m2dPath}\Resource\asset-web-metadata.m2d"); @@ -51,3 +50,48 @@ public static void UnknownAttributeHandler(object? sender, XmlAttributeEventArgs Debug.Print("Missing attribute {0}, expected [{1}]", e.Attr.Name, e.ExpectedAttributes); } } + +// We still want to load all files from the KR version, not only Xml.m2d +public static class TestUtilsKr { + public static readonly M2dReader XmlReader; + public static readonly M2dReader ServerReader; + public static readonly M2dReader ExportedReader; + public static readonly M2dReader AssetMetadataReader; + public static readonly AssetIndex AssetIndex; + public static readonly List ModelM2dReaders; + + static TestUtilsKr() { + DotEnv.Load(); + string? m2dPath = Environment.GetEnvironmentVariable("KMS2_DATA_FOLDER"); + if (string.IsNullOrEmpty(m2dPath)) { + throw new Exception("KMS2_DATA_FOLDER is not set"); + } + + XmlReader = new M2dReader(@$"{m2dPath}\Xml.m2d"); + ExportedReader = new M2dReader(@$"{m2dPath}\Resource\Exported.m2d"); + ServerReader = new M2dReader(@$"{m2dPath}\Server.m2d"); + AssetMetadataReader = new M2dReader(@$"{m2dPath}\Resource\asset-web-metadata.m2d"); + AssetIndex = new AssetIndex(AssetMetadataReader); + ModelM2dReaders = new List() { + new PrefixedM2dReader("/library/", $@"{m2dPath}\Resource\Library.m2d"), + new PrefixedM2dReader("/model/map/", $@"{m2dPath}\Resource\Model\Map.m2d"), + new PrefixedM2dReader("/model/effect/", $@"{m2dPath}\Resource\Model\Effect.m2d"), + new PrefixedM2dReader("/model/camera/", $@"{m2dPath}\Resource\Model\Camera.m2d"), + new PrefixedM2dReader("/model/tool/", $@"{m2dPath}\Resource\Model\Tool.m2d"), + new PrefixedM2dReader("/model/item/", $@"{m2dPath}\Resource\Model\Item.m2d"), + new PrefixedM2dReader("/model/npc/", $@"{m2dPath}\Resource\Model\Npc.m2d"), + new PrefixedM2dReader("/model/path/", $@"{m2dPath}\Resource\Model\Path.m2d"), + new PrefixedM2dReader("/model/character/", $@"{m2dPath}\Resource\Model\Character.m2d"), + new PrefixedM2dReader("/model/textures/", $@"{m2dPath}\Resource\Model\Textures.m2d"), + }; + } + + public static void UnknownElementHandler(object? sender, XmlElementEventArgs e) { + Debug.Print("Missing element {0}, expected [{1}]", e.Element.Name, e.ExpectedElements); + } + + public static void UnknownAttributeHandler(object? sender, XmlAttributeEventArgs e) { + Debug.Print("Missing attribute {0}, expected [{1}]", e.Attr.Name, e.ExpectedAttributes); + } +} + diff --git a/Maple2.File.Tests/XBlockParserTest.cs b/Maple2.File.Tests/XBlockParserTest.cs index da7554a..aa76378 100644 --- a/Maple2.File.Tests/XBlockParserTest.cs +++ b/Maple2.File.Tests/XBlockParserTest.cs @@ -9,14 +9,14 @@ namespace Maple2.File.Tests; [TestClass] public class XBlockParserTest { - [TestMethod] - public void TestConversion() { - // var flatConverter = new FlatToModel(TestUtils.ExportedReader, TestUtils.AssetMetadataReader); - // flatConverter.Convert(); + // [TestMethod] + // public void TestConversion() { + // var flatConverter = new FlatToModel(TestUtils.ExportedReader, TestUtils.AssetMetadataReader); + // flatConverter.Convert(); - // var xblockConverter = new XBlockToBlock(TestUtils.ExportedReader); - // xblockConverter.Convert(); - } + // var xblockConverter = new XBlockToBlock(TestUtils.ExportedReader); + // xblockConverter.Convert(); + // } [TestMethod] public void TestXBlockParser() { @@ -35,6 +35,23 @@ public void TestXBlockParser() { }); } + [TestMethod] + public void TestXBlockParserKr() { + var index = new FlatTypeIndex(TestUtilsKr.ExportedReader); + var parser = new XBlockParser(TestUtilsKr.ExportedReader, index); + // Console.WriteLine(index.GetType("Portal_entrance").GetProperty("frontOffset")); + + parser.ParseMap("02000070_in", entities => { + foreach (IMapEntity? entity in entities) { + if (entity is IPortal portal) { + Console.WriteLine(entity.EntityName); + Console.WriteLine(portal.ModelName); + Console.WriteLine(portal.frontOffset); + } + } + }); + } + [Ignore] public void TestXBlockParserAll() { var sw = new Stopwatch(); @@ -59,3 +76,4 @@ IEnumerable Process(IEnumerable entities) { } } } + diff --git a/Maple2.File.sln b/Maple2.File.sln index 4acb077..ba3b3af 100644 --- a/Maple2.File.sln +++ b/Maple2.File.sln @@ -13,6 +13,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maple2.File.Flat", "Maple2. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maple2.File.Tests", "Maple2.File.Tests\Maple2.File.Tests.csproj", "{7A3AFE6F-9291-4392-9605-F2BC21274D1D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B6C9B84C-C672-44CC-95DF-DA79AAD31ED2}" + ProjectSection(SolutionItems) = preProject + .env = .env + .env.example = .env.example + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/global.json b/global.json new file mode 100644 index 0000000..dad2db5 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file