diff --git a/Maple2.File.Parser/BanWordParser.cs b/Maple2.File.Parser/BanWordParser.cs new file mode 100644 index 0000000..d360c85 --- /dev/null +++ b/Maple2.File.Parser/BanWordParser.cs @@ -0,0 +1,54 @@ +using System.Diagnostics; +using System.Xml; +using System.Xml.Serialization; +using Maple2.File.IO; +using Maple2.File.IO.Crypto.Common; +using Maple2.File.Parser.Xml.String; + +namespace Maple2.File.Parser; + +public class BanWordParser { + private readonly M2dReader xmlReader; + private readonly XmlSerializer nameSerializer; + + public BanWordParser(M2dReader xmlReader) { + this.xmlReader = xmlReader; + nameSerializer = new XmlSerializer(typeof(StringMapping)); + } + + public IEnumerable<(int Id, string Name)> ParseBanWords() { + int i = 0; + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.Contains("banword") && !entry.Name.Contains("ugc"))) { + XmlReader reader = xmlReader.GetXmlReader(entry); + var mapping = nameSerializer.Deserialize(reader) as StringMapping; + + Debug.Assert(mapping != null); + + Dictionary banWords = mapping.key.ToDictionary(_ => i++, key => key.name); + foreach (var banWord in banWords) { + if (string.IsNullOrEmpty(banWord.Value)) { + continue; + } + yield return (banWord.Key, banWord.Value); + } + } + } + + public IEnumerable<(int Id, string Name)> ParseUgcBanWords() { + int i = 0; + foreach (PackFileEntry entry in xmlReader.Files.Where(entry => entry.Name.Contains("ugcbanword"))) { + XmlReader reader = xmlReader.GetXmlReader(entry); + var mapping = nameSerializer.Deserialize(reader) as StringMapping; + + Debug.Assert(mapping != null); + + Dictionary banWords = mapping.key.ToDictionary(_ => i++, key => key.name); + foreach (var banWord in banWords) { + if (string.IsNullOrEmpty(banWord.Value)) { + continue; + } + yield return (banWord.Key, banWord.Value); + } + } + } +} diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj index 78ab12d..cb31365 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.3.3 + 2.3.4 net8.0 README.md enable diff --git a/Maple2.File.Tests/BanWordParserTest.cs b/Maple2.File.Tests/BanWordParserTest.cs new file mode 100644 index 0000000..c0aff33 --- /dev/null +++ b/Maple2.File.Tests/BanWordParserTest.cs @@ -0,0 +1,39 @@ +using Maple2.File.Parser; +using Maple2.File.Parser.Enum; +using Maple2.File.Parser.Tools; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Maple2.File.Tests; + +[TestClass] +public class BanWordParserTest { + [TestMethod] + public void TestBanWordParser() { + var locale = Locale.NA; + Filter.Load(TestUtils.XmlReader, locale.ToString(), "Live"); + var parser = new BanWordParser(TestUtils.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseBanWords()) { + Assert.IsTrue(id >= 0); + Assert.IsFalse(string.IsNullOrEmpty(name)); + count++; + } + Assert.AreEqual(6179, count); + } + + [TestMethod] + public void TestUgcBanWordParser() { + var locale = Locale.NA; + Filter.Load(TestUtils.XmlReader, locale.ToString(), "Live"); + var parser = new BanWordParser(TestUtils.XmlReader); + + int count = 0; + foreach ((int id, string name) in parser.ParseUgcBanWords()) { + Assert.IsTrue(id >= 0); + Assert.IsFalse(string.IsNullOrEmpty(name)); + count++; + } + Assert.AreEqual(1208, count); + } +}