diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj
index 59a01cb..ddfa4a9 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.2.8
+ 2.2.9
net8.0
README.md
enable
diff --git a/Maple2.File.Parser/TableParser.cs b/Maple2.File.Parser/TableParser.cs
index f14f4ba..04e3b86 100644
--- a/Maple2.File.Parser/TableParser.cs
+++ b/Maple2.File.Parser/TableParser.cs
@@ -99,6 +99,7 @@ public class TableParser {
private readonly XmlSerializer weddingRewardSerializer;
private readonly XmlSerializer weddingSkillSerializer;
private readonly XmlSerializer smartPushSerializer;
+ private readonly XmlSerializer seasonDataSerializer;
private readonly string locale;
@@ -191,6 +192,7 @@ public TableParser(M2dReader xmlReader) {
weddingRewardSerializer = new XmlSerializer(typeof(WeddingRewardRoot));
weddingSkillSerializer = new XmlSerializer(typeof(WeddingSkillRoot));
smartPushSerializer = new XmlSerializer(typeof(SmartPushRoot));
+ seasonDataSerializer = new XmlSerializer(typeof(SeasonDataRoot));
locale = FeatureLocaleFilter.Locale.ToLower();
@@ -1399,4 +1401,103 @@ public IEnumerable ParseJobTableKR() {
yield return (entry.id, entry);
}
}
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataArcade() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_arcade.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataBossColosseum() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_bosscolosseum.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataDarkStream() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_darkstream.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataGuildPvp() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_guildpvp.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataMapleSurvival() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_maplesurvival.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataMapleSurvivalSquad() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_maplesurvival_squad.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataPvp() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_pvp.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataUgcMapCommendation() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_ugcmapcommendation.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
+
+ public IEnumerable<(int Id, SeasonData Data)> ParseSeasonDataWorldChampion() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry($"table/{locale}/seasondata_worldchampion.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = seasonDataSerializer.Deserialize(reader) as SeasonDataRoot;
+ Debug.Assert(data != null);
+
+ foreach (SeasonData entry in data.Season) {
+ yield return (entry.seasonID, entry);
+ }
+ }
}
diff --git a/Maple2.File.Parser/Xml/Table/SeasonData.cs b/Maple2.File.Parser/Xml/Table/SeasonData.cs
new file mode 100644
index 0000000..6260f57
--- /dev/null
+++ b/Maple2.File.Parser/Xml/Table/SeasonData.cs
@@ -0,0 +1,31 @@
+using System.Xml.Serialization;
+
+namespace Maple2.File.Parser.Xml.Table;
+
+// ./data/xml/table/na/seasondata_arcade.xml
+// ./data/xml/table/na/seasondata_bosscolosseum.xml
+// ./data/xml/table/na/seasondata_darkstream.xml
+// ./data/xml/table/na/seasondata_guildpvp.xml
+// ./data/xml/table/na/seasondata_maplesurvival.xml
+// ./data/xml/table/na/seasondata_maplesurvival_squad.xml
+// ./data/xml/table/na/seasondata_pvp.xml
+// ./data/xml/table/na/seasondata_ugcmapcommendation.xml
+// ./data/xml/table/na/seasondata_worldchampion.xml
+[XmlRoot("ms2")]
+public class SeasonDataRoot {
+ [XmlElement] public List Season;
+}
+
+public partial class SeasonData {
+ [XmlAttribute] public int seasonID;
+ [XmlAttribute] public string seasonName = string.Empty;
+ [XmlAttribute] public string eventStart = string.Empty;
+ [XmlAttribute] public string eventEnd = string.Empty;
+ [XmlAttribute] public int grade1;
+ [XmlAttribute] public int grade2;
+ [XmlAttribute] public int grade3;
+ [XmlAttribute] public int grade4;
+ [XmlAttribute] public int grade5;
+ [XmlAttribute] public int grade6;
+ [XmlAttribute] public int grade7;
+}
diff --git a/Maple2.File.Tests/TableParserTest.cs b/Maple2.File.Tests/TableParserTest.cs
index c2d18b2..c82263d 100644
--- a/Maple2.File.Tests/TableParserTest.cs
+++ b/Maple2.File.Tests/TableParserTest.cs
@@ -678,5 +678,44 @@ public void TestSmartPush() {
continue;
}
}
+
+ [TestMethod]
+ public void TestSeasonData() {
+ foreach ((_, _) in _parser.ParseSeasonDataArcade()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataBossColosseum()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataDarkStream()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataGuildPvp()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataMapleSurvival()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataMapleSurvivalSquad()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataPvp()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataUgcMapCommendation()) {
+ continue;
+ }
+
+ foreach ((_, _) in _parser.ParseSeasonDataWorldChampion()) {
+ continue;
+ }
+ }
}