diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj
index f275388..985a1a1 100644
--- a/Maple2.File.Parser/Maple2.File.Parser.csproj
+++ b/Maple2.File.Parser/Maple2.File.Parser.csproj
@@ -13,7 +13,7 @@
MapleStory2, File, Parser, m2d, xml
true
- 2.4.27
+ 2.4.28
net8.0
README.md
enable
diff --git a/Maple2.File.Parser/TableParser.cs b/Maple2.File.Parser/TableParser.cs
index bff97b4..b058a08 100644
--- a/Maple2.File.Parser/TableParser.cs
+++ b/Maple2.File.Parser/TableParser.cs
@@ -882,6 +882,18 @@ public IEnumerable ParseJobTableNew() {
}
}
+ // One entry per title id that survives the feature and locale filter, which is also the set the
+ // client can name. A title missing here shows no row in the client's title dropdown.
+ public IEnumerable<(int Id, string Name)> ParseTitleName() {
+ XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry($"{language}/titlename.xml"));
+ var mapping = nameSerializer.Deserialize(reader) as StringMapping;
+ Debug.Assert(mapping != null);
+
+ foreach (Key key in mapping.key) {
+ yield return (int.Parse(key.id), key.name);
+ }
+ }
+
public IEnumerable<(int Id, IDictionary>)> ParseIndividualItemDrop() {
string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/individualitemdrop.xml")));
xml = Sanitizer.SanitizeBool(xml);
diff --git a/Maple2.File.Tests/TableParserTest.cs b/Maple2.File.Tests/TableParserTest.cs
index 78ab3a6..4dd9b30 100644
--- a/Maple2.File.Tests/TableParserTest.cs
+++ b/Maple2.File.Tests/TableParserTest.cs
@@ -396,6 +396,18 @@ public void TestParseTitleTag() {
}
}
+ [TestMethod]
+ public void TestParseTitleName() {
+ Dictionary names = _parser.ParseTitleName().ToDictionary(entry => entry.Id, entry => entry.Name);
+
+ // Rows of titlename.xml, read against feature.xml under Live NA.
+ Assert.AreEqual("Ace Archer", names[10000655]);
+ // feature="Fame_Geo01", which is NA="99".
+ Assert.IsFalse(names.ContainsKey(10000754));
+ // locale="CN" only.
+ Assert.IsFalse(names.ContainsKey(10000750));
+ }
+
[TestMethod]
public void TestIndividualItemDrop() {
foreach ((_, _) in _parser.ParseIndividualItemDrop()) {