Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Maple2.File.Generator/XmlArrayGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

namespace Maple2.File.Generator;

[Generator]

Check warning on line 9 in Maple2.File.Generator/XmlArrayGenerator.cs

View workflow job for this annotation

GitHub Actions / build

This compiler extension should not be implemented in an assembly with target framework '.NET 8.0'. References to other target frameworks will cause the compiler to behave unpredictably. (https://github.com/dotnet/roslyn-analyzers/blob/main/docs/rules/RS1041.md)

Check warning on line 9 in Maple2.File.Generator/XmlArrayGenerator.cs

View workflow job for this annotation

GitHub Actions / build

This compiler extension should not be implemented in an assembly containing a reference to Microsoft.CodeAnalysis.Workspaces. The Microsoft.CodeAnalysis.Workspaces assembly is not provided during command line compilation scenarios, so references to it could cause the compiler extension to behave unpredictably. (https://github.com/dotnet/roslyn-analyzers/blob/main/docs/rules/RS1038.md)
public class XmlArrayGenerator : XmlGenerator {

Check warning on line 10 in Maple2.File.Generator/XmlArrayGenerator.cs

View workflow job for this annotation

GitHub Actions / build

'Maple2.File.Generator.XmlArrayGenerator': A project containing analyzers or source generators should specify the property '<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>'
private static readonly SourceText attributeSource =
Assembly.GetExecutingAssembly().LoadSource("M2dArrayAttribute.cs");
private static readonly DiagnosticDescriptor typeError = new DiagnosticDescriptor(
Expand Down Expand Up @@ -66,7 +66,7 @@

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) {
Expand Down
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/ConditionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/DungeonType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public enum DungeonTimerType {
public enum DungeonBossRankingType {
None = 0,
Kill = 1,
kill = Kill,
Damage = 2,
KillRumble = 3,
MultiKill = 4,
Expand Down
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/ItemExchangeScrollType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public enum ItemExchangeScrollType {
exchange = 1,
updated = 2,
trading = 3,
upgrade = 4,
}
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/NameTagSymbolConditionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public enum NameTagSymbolConditionType {
adventure_level,
Burning,
survivallevel,
return_user,
}
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/QuestPropertyType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public enum QuestPropertyType {
special = 0,
hidebeginablelist = 1,
availablecompletionticket = 2,
hideworldmap = 3,
}
1 change: 1 addition & 0 deletions Maple2.File.Parser/Enum/QuestRewardType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public enum QuestRewardType {
unknown = 0,
item = 1,
skillPoint = 2,
SkillPoint = skillPoint,
statPoint = 3,
}
114 changes: 100 additions & 14 deletions Maple2.File.Parser/ItemOptionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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;
Expand All @@ -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));
Expand All @@ -82,6 +127,20 @@ public IEnumerable<ItemOptionConstantData> ParseConstant() {
}
}

public IEnumerable<ItemOptionConstant> 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<ItemOptionData> ParseRandom() {
foreach (string suffix in randomSuffix) {
string filename = $"itemoption/option/random/itemoptionrandom_{suffix}.xml";
Expand All @@ -98,6 +157,21 @@ public IEnumerable<ItemOptionData> ParseRandom() {
}
}

public IEnumerable<ItemOptionRandomKR> 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<ItemOptionData> ParseStatic() {
foreach (string suffix in staticSuffix) {
string filename = $"itemoption/option/static/itemoptionstatic_{suffix}.xml";
Expand All @@ -114,6 +188,18 @@ public IEnumerable<ItemOptionData> ParseStatic() {
}
}

public IEnumerable<MergeOptionKR> 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<MergeOption> ParseMergeOptionBase() {
string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/itemmergeoptionbase.xml")));
var reader = XmlReader.Create(new StringReader(xml));
Expand Down
51 changes: 33 additions & 18 deletions Maple2.File.Parser/ItemParser.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<T>() where T : class {
Dictionary<int, string> 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<int, string> 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<int, string> 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);
}
}
40 changes: 32 additions & 8 deletions Maple2.File.Parser/MapParser.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -17,26 +18,49 @@ 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<int, string> mapNames = ParseMapNames();

Dictionary<int, string> mapNames = mapping.key.ToDictionary(key => int.Parse(key.id), key => key.name);
IEnumerable<PackFileEntry> 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);

MapData data = root.environment;
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<int, string> 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);
}
}
Loading
Loading