public static List <ExpMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries) { List <ExpMetadata> expList = new List <ExpMetadata>(); foreach (PackFileEntry entry in entries) { if (!entry.Name.StartsWith("table/nextexp")) { continue; } XmlReader reader = m2dFile.GetReader(entry.FileHeader); while (reader.Read()) { ExpMetadata expTable = new ExpMetadata(); if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Name == "exp" && reader["level"] != "0") { expTable.Level = byte.Parse(reader["level"]); expTable.Experience = long.Parse(reader["value"]); expList.Add(expTable); } } } return(expList); }
public static List <InsigniaMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries) { // Iterate over preset objects to later reference while iterating over exported maps List <InsigniaMetadata> insignias = new List <InsigniaMetadata>(); foreach (PackFileEntry entry in entries) { if (!entry.Name.StartsWith("table/nametagsymbol")) { continue; } using XmlReader reader = m2dFile.GetReader(entry.FileHeader); while (reader.Read()) { InsigniaMetadata metadata = new InsigniaMetadata(); if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Name == "symbol") { metadata.InsigniaId = short.Parse(reader["id"]); metadata.ConditionType = reader["conditionType"]; metadata.TitleId = reader["code"] == "" ? 0 : int.Parse(reader["code"]); } insignias.Add(metadata); } } return(insignias); }
public static List <ItemMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries) { List <ItemMetadata> items = new List <ItemMetadata>(); foreach (PackFileEntry entry in entries) { if (!entry.Name.StartsWith("item/")) { continue; } ItemMetadata metadata = new ItemMetadata(); string itemId = Path.GetFileNameWithoutExtension(entry.Name); metadata.Id = int.Parse(itemId); Debug.Assert(metadata.Id > 0, $"Invalid Id {metadata.Id} from {itemId}"); using XmlReader reader = m2dFile.GetReader(entry.FileHeader); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "slot") { bool result = Enum.TryParse <ItemSlot>(reader["name"], out metadata.Slot); if (!result && !string.IsNullOrEmpty(reader["name"])) { throw new ArgumentException("Failed to parse item slot:" + reader["name"]); } } else if (reader.Name == "property") { try { byte type = byte.Parse(reader["type"]); byte subType = byte.Parse(reader["subtype"]); bool skin = byte.Parse(reader["skin"]) != 0; metadata.Tab = GetTab(type, subType, skin); metadata.IsTemplate = byte.Parse(reader["skinType"] ?? "0") == 99; } catch (Exception e) { Console.WriteLine($"Failed {itemId}: {e.Message}"); } metadata.SlotMax = int.Parse(reader["slotMax"]); } } } items.Add(metadata); } return(items); }
public static List <ItemMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries) { List <ItemMetadata> items = new List <ItemMetadata>(); foreach (PackFileEntry entry in entries) { if (!entry.Name.StartsWith("item/")) { continue; } ItemMetadata metadata = new ItemMetadata(); string itemId = Path.GetFileNameWithoutExtension(entry.Name); if (items.Exists(item => item.Id.ToString() == itemId)) { //Console.WriteLine($"Duplicate {entry.Name} was already added."); continue; } metadata.Id = int.Parse(itemId); Debug.Assert(metadata.Id > 0, $"Invalid Id {metadata.Id} from {itemId}"); using XmlReader reader = m2dFile.GetReader(entry.FileHeader); while (reader.Read()) { if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Name == "slot") { bool result = Enum.TryParse <ItemSlot>(reader["name"], out metadata.Slot); if (!result && !string.IsNullOrEmpty(reader["name"])) { throw new ArgumentException("Failed to parse item slot:" + reader["name"]); } } else if (reader.Name == "gem") { bool result = Enum.TryParse <GemSlot>(reader["system"], out metadata.Gem); if (!result && !string.IsNullOrEmpty(reader["system"])) { throw new ArgumentException("Failed to parse item slot:" + reader["system"]); } } else if (reader.Name == "property") { try { byte type = byte.Parse(reader["type"]); byte subType = byte.Parse(reader["subtype"]); bool skin = byte.Parse(reader["skin"]) != 0; metadata.Tab = GetTab(type, subType, skin); metadata.IsTemplate = byte.Parse(reader["skinType"] ?? "0") == 99; } catch (Exception e) { Console.WriteLine($"Failed {itemId}: {e.Message}"); } metadata.SlotMax = int.Parse(reader["slotMax"]); } else if (reader.Name == "option") { int rarity = 1; if (reader["constant"].Length == 1) { rarity = int.Parse(reader["constant"]); } metadata.Rarity = rarity; } else if (reader.Name == "function") { string contentType = reader["name"]; if (contentType != "OpenItemBox" && contentType != "SelectItemBox") { continue; } // selection boxes are SelectItemBox and 1,boxid // normal boxes are OpenItemBox and 0,1,0,boxid // fragments are OpenItemBox and 0,1,0,boxid,required_amount List <string> parameters = new List <string>(reader["parameter"].Split(",")); // Remove empty params parameters.RemoveAll(param => param.Length == 0); if (parameters.Count < 2) { continue; } string boxId = contentType == "OpenItemBox" ? parameters[3] : parameters[1]; foreach (PackFileEntry innerEntry in entries) { if (!innerEntry.Name.StartsWith("table/individualitemdrop") && !innerEntry.Name.StartsWith("table/na/individualitemdrop")) { continue; } if (metadata.Content.Count > 0) { continue; } // Parse XML XmlDocument document = m2dFile.GetDocument(innerEntry.FileHeader); XmlNodeList individualBoxItems = document.SelectNodes($"/ms2/individualDropBox[@individualDropBoxID={boxId}]"); foreach (XmlNode individualBoxItem in individualBoxItems) { int id = int.Parse(individualBoxItem.Attributes["item"].Value); int minAmount = int.Parse(individualBoxItem.Attributes["minCount"].Value); int maxAmount = int.Parse(individualBoxItem.Attributes["maxCount"].Value); int dropGroup = int.Parse(individualBoxItem.Attributes["dropGroup"].Value); int smartDropRate = string.IsNullOrEmpty(individualBoxItem.Attributes["smartDropRate"]?.Value) ? 0 : int.Parse(individualBoxItem.Attributes["smartDropRate"].Value); int rarity = string.IsNullOrEmpty(individualBoxItem.Attributes["PackageUIShowGrade"]?.Value) ? 0 : int.Parse(individualBoxItem.Attributes["PackageUIShowGrade"].Value); int enchant = string.IsNullOrEmpty(individualBoxItem.Attributes["enchantLevel"]?.Value) ? 0 : int.Parse(individualBoxItem.Attributes["enchantLevel"].Value); int id2 = string.IsNullOrEmpty(individualBoxItem.Attributes["item2"]?.Value) ? 0 : int.Parse(individualBoxItem.Attributes["item2"].Value); // Skip already existing item, this may need to check for locales but not certain if (metadata.Content.Exists(content => content.Id == id)) { continue; } metadata.Content.Add(new ItemContent(id, minAmount, maxAmount, dropGroup, smartDropRate, rarity, enchant, id2)); } } } else if (reader.Name == "MusicScore") { int playCount = int.Parse(reader["playCount"]); metadata.PlayCount = playCount; } else if (reader.Name == "limit") { if (!string.IsNullOrEmpty(reader["recommendJobs"])) { List <string> temp = new List <string>(reader["recommendJobs"].Split(",")); foreach (string item in temp) { metadata.RecommendJobs.Add(int.Parse(item)); } } } } items.Add(metadata); } return(items); }
public static List <QuestMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries) { List <QuestMetadata> quests = new List <QuestMetadata>(); foreach (PackFileEntry entry in entries) { if (!entry.Name.StartsWith("quest/")) { continue; } QuestMetadata metadata = new QuestMetadata(); using XmlReader reader = m2dFile.GetReader(entry.FileHeader); while (reader.Read()) { if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Name == "environment" && (reader["locale"] != "NA" && reader["locale"] != "")) // only reading quests for NA or all environments { reader.Skip(); } else if (reader.Name == "environment") { metadata.Feature = reader["feature"]; metadata.Locale = reader["locale"]; } else if (reader.Name == "basic") { metadata.Basic.ChapterID = string.IsNullOrEmpty(reader["chapterID"]) ? 0 : int.Parse(reader["chapterID"]); metadata.Basic.QuestID = string.IsNullOrEmpty(reader["questID"]) ? 0 : int.Parse(reader["questID"]); metadata.Basic.QuestType = string.IsNullOrEmpty(reader["questType"]) ? 0 : byte.Parse(reader["questType"]); metadata.Basic.Account = string.IsNullOrEmpty(reader["account"]) ? 0 : byte.Parse(reader["account"]); metadata.Basic.StandardLevel = string.IsNullOrEmpty(reader["standardLevel"]) ? 0 : int.Parse(reader["standardLevel"]); metadata.Basic.AutoStart = string.IsNullOrEmpty(reader["autoStart"]) ? 0 : byte.Parse(reader["autoStart"]); metadata.Basic.DisableGiveup = string.IsNullOrEmpty(reader["disableGiveup"]) ? 0 : byte.Parse(reader["disableGiveup"]); metadata.Basic.ExceptChapterClear = string.IsNullOrEmpty(reader["exceptChapterClear"]) ? 0 : int.Parse(reader["exceptChapterClear"]); metadata.Basic.Repeatable = string.IsNullOrEmpty(reader["repeatable"]) ? 0 : byte.Parse(reader["repeatable"]); metadata.Basic.UsePeriod = reader["usePeriod"]; metadata.Basic.EventTag = reader["eventTag"]; metadata.Basic.Locking = string.IsNullOrEmpty(reader["locking"]) ? 0 : byte.Parse(reader["locking"]); metadata.Basic.TabIndex = string.IsNullOrEmpty(reader["tabIndex"]) ? 0 : int.Parse(reader["tabIndex"]); metadata.Basic.ForceRegistGuide = string.IsNullOrEmpty(reader["forceRegistGuide"]) ? 0 : byte.Parse(reader["forceRegistGuide"]); metadata.Basic.UseNavigation = reader["useNavi"] == "FALSE" ? false : true; } else if (reader.Name == "notify") { metadata.Notify.CompleteUiEffect = reader["completeUiEffect"]; metadata.Notify.AcceptSoundKey = reader["acceptSoundKey"]; metadata.Notify.CompleteSoundKey = reader["completeSoundKey"]; } else if (reader.Name == "require") { metadata.Require.Level = string.IsNullOrEmpty(reader["level"]) ? 0 : short.Parse(reader["level"]); metadata.Require.MaxLevel = string.IsNullOrEmpty(reader["maxLevel"]) ? 0 : short.Parse(reader["maxLevel"]); if (!string.IsNullOrEmpty(reader["job"])) { List <string> temp = new List <string>(reader["job"].Split(",")); foreach (string item in temp) { metadata.Require.Job.Add(short.Parse(item)); } } if (!string.IsNullOrEmpty(reader["quest"])) { List <string> temp = new List <string>(reader["quest"].Split(",")); foreach (string item in temp) { metadata.Require.RequiredQuests.Add(int.Parse(item)); } } if (!string.IsNullOrEmpty(reader["selectableQuest"])) { List <string> temp = new List <string>(reader["selectableQuest"].Split(",")); foreach (string item in temp) { metadata.Require.SelectableQuest.Add(int.Parse(item)); } } if (!string.IsNullOrEmpty(reader["unrequire"])) { List <string> temp = new List <string>(reader["unrequire"].Split(",")); foreach (string item in temp) { metadata.Require.Unrequire.Add(int.Parse(item)); } } metadata.Require.Field = string.IsNullOrEmpty(reader["field"]) ? 0 : int.Parse(reader["field"]); metadata.Require.Achievement = string.IsNullOrEmpty(reader["achievement"]) ? 0 : int.Parse(reader["achievement"]); if (!string.IsNullOrEmpty(reader["unreqAchievement"])) { List <string> temp = new List <string>(reader["unreqAchievement"].Split(",")); foreach (string item in temp) { metadata.Require.UnreqAchievement.Add(int.Parse(item)); } } metadata.Require.GroupID = string.IsNullOrEmpty(reader["groupID"]) ? 0 : int.Parse(reader["groupID"]); metadata.Require.DayOfWeek = reader["dayOfWeek"]; metadata.Require.GearScore = string.IsNullOrEmpty(reader["gearScore"]) ? 0 : int.Parse(reader["gearScore"]); } else if (reader.Name == "start") { metadata.StartNpc = int.Parse(reader["npc"]); } else if (reader.Name == "complete") { metadata.CompleteNpc = int.Parse(reader["npc"]); } else if (reader.Name == "completeReward") { metadata.Reward.Exp = string.IsNullOrEmpty(reader["exp"]) ? 0 : int.Parse(reader["exp"]); metadata.Reward.RelativeExp = reader["relativeExp"]; metadata.Reward.Money = string.IsNullOrEmpty(reader["money"]) ? 0 : int.Parse(reader["money"]); metadata.Reward.Karma = string.IsNullOrEmpty(reader["karma"]) ? 0 : int.Parse(reader["karma"]); metadata.Reward.Lu = string.IsNullOrEmpty(reader["lu"]) ? 0 : int.Parse(reader["lu"]); } else if (reader.Name == "essentialJobItem" || reader.Name == "globalEssentialItem" || reader.Name == "globalEssentialJobItem") { int itemid = string.IsNullOrEmpty(reader["code"]) ? 0 : int.Parse(reader["code"]); byte rank = string.IsNullOrEmpty(reader["rank"]) ? 0 : byte.Parse(reader["rank"]); int count = string.IsNullOrEmpty(reader["count"]) ? 0 : int.Parse(reader["count"]); QuestRewardItem item = new QuestRewardItem(itemid, rank, count); metadata.RewardItem.Add(item); } else if (reader.Name == "progressMap") { if (!string.IsNullOrEmpty(reader["progressMap"])) { List <string> temp = new List <string>(reader["progressMap"].Split(",")); foreach (string item in temp) { metadata.ProgressMap.Add(int.Parse(item)); } } } else if (reader.Name == "guide") { metadata.Guide.Type = reader["guideType"]; metadata.Guide.Icon = reader["guideIcon"]; metadata.Guide.MinLevel = string.IsNullOrEmpty(reader["guideMinLevel"]) ? 0 : byte.Parse(reader["guideMinLevel"]); metadata.Guide.MaxLevel = string.IsNullOrEmpty(reader["guideMaxLevel"]) ? 0 : byte.Parse(reader["guideMaxLevel"]); metadata.Guide.Group = reader["guideGroup"]; } else if (reader.Name == "gotoNpc") { metadata.Npc.Enable = string.IsNullOrEmpty(reader["enable"]) ? 0 : byte.Parse(reader["enable"]); metadata.Npc.GoToField = string.IsNullOrEmpty(reader["gotoField"]) ? 0 : int.Parse(reader["gotoField"]); metadata.Npc.GoToPortal = string.IsNullOrEmpty(reader["gotoPortal"]) ? 0 : int.Parse(reader["gotoPortal"]); } else if (reader.Name == "gotoDungeon") { metadata.Dungeon.State = string.IsNullOrEmpty(reader["state"]) ? 0 : byte.Parse(reader["state"]); metadata.Dungeon.GoToDungeon = string.IsNullOrEmpty(reader["gotoDungeon"]) ? 0 : int.Parse(reader["gotoDungeon"]); metadata.Dungeon.GoToInstanceID = string.IsNullOrEmpty(reader["gotoInstanceID"]) ? 0 : int.Parse(reader["gotoInstanceID"]); } else if (reader.Name == "remoteAccept") { metadata.RemoteAccept.UseRemote = reader["useRemote"]; metadata.RemoteAccept.RequireField = string.IsNullOrEmpty(reader["requireField"]) ? 0 : int.Parse(reader["requireField"]); } else if (reader.Name == "remoteComplete") { metadata.RemoteComplete.UseRemote = reader["useRemote"]; metadata.RemoteComplete.RequireField = string.IsNullOrEmpty(reader["requireField"]) ? 0 : int.Parse(reader["requireField"]); metadata.RemoteComplete.RequireDungeonClear = string.IsNullOrEmpty(reader["requireDungeonClear"]) ? 0 : int.Parse(reader["requireDungeonClear"]); } else if (reader.Name == "summonPortal") { metadata.SummonPortal.FieldID = string.IsNullOrEmpty(reader["fieldID"]) ? 0 : int.Parse(reader["fieldID"]); metadata.SummonPortal.PortalID = string.IsNullOrEmpty(reader["portalID"]) ? 0 : int.Parse(reader["portalID"]); } else if (reader.Name == "eventMission") { metadata.Event = reader["event"]; } else if (reader.Name == "condition") { string Type = reader["type"]; string Code = reader["code"]; int Value = string.IsNullOrEmpty(reader["value"]) ? 0 : int.Parse(reader["value"]); List <string> temp = null; if (!string.IsNullOrEmpty(reader["target"])) { temp = new List <string>(reader["target"].Split(",")); } metadata.Condition.Add(new QuestCondition(Type, Code, Value, temp)); } else if (reader.Name == "navi") { string NaviType = reader["type"]; string NaviCode = reader["code"]; int NaviMap = string.IsNullOrEmpty(reader["map"]) ? 0 : int.Parse(reader["map"]); metadata.Navigation.Add(new QuestNavigation(NaviType, NaviCode, NaviMap)); } } quests.Add(metadata); } return(quests); }