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
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# To use with docker, rename MS2_DATA_FOLDER to MS2_DOCKER_DATA_FOLDER
MS2_DATA_FOLDER=C:/Nexon/Library/maplestory2/Data/

# Primary language. Mainly used for searching on black market, commands, etc.
# EN, KR, CN, JP, DE, PR
LANGUAGE=EN

# Database connection

DB_IP=localhost
Expand Down
1 change: 1 addition & 0 deletions Maple2.Database/Context/MetadataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ private static void ConfigureQuestMetadata(EntityTypeBuilder<QuestMetadata> buil
builder.Property(quest => quest.GoToDungeon).HasJsonConversion();
builder.Property(quest => quest.Dispatch).HasJsonConversion();
builder.Property(quest => quest.Mentoring).HasJsonConversion();
builder.Property(quest => quest.SummonPortal).HasJsonConversion();
}

private static void ConfigureRideMetadata(EntityTypeBuilder<RideMetadata> builder) {
Expand Down
10 changes: 10 additions & 0 deletions Maple2.Database/Storage/Metadata/TableMetadataStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class TableMetadataStorage {
private readonly Lazy<BannerTable> bannerTable;
private readonly Lazy<WeddingTable> weddingTable;
private readonly Lazy<RewardContentTable> rewardContentTable;
private readonly Lazy<SeasonDataTable> seasonDataTable;
private readonly Lazy<SmartPushTable> smartPushTable;
private readonly Lazy<AutoActionTable> autoActionTable;

private readonly Lazy<EnchantScrollTable> enchantScrollTable;
private readonly Lazy<ItemRemakeScrollTable> itemRemakeScrollTable;
Expand Down Expand Up @@ -109,6 +112,9 @@ public class TableMetadataStorage {
public BannerTable BannerTable => bannerTable.Value;
public WeddingTable WeddingTable => weddingTable.Value;
public RewardContentTable RewardContentTable => rewardContentTable.Value;
public SeasonDataTable SeasonDataTable => seasonDataTable.Value;
public SmartPushTable SmartPushTable => smartPushTable.Value;
public AutoActionTable AutoActionTable => autoActionTable.Value;

public EnchantScrollTable EnchantScrollTable => enchantScrollTable.Value;
public ItemRemakeScrollTable ItemRemakeScrollTable => itemRemakeScrollTable.Value;
Expand Down Expand Up @@ -191,6 +197,10 @@ public TableMetadataStorage(MetadataContext context) {
dungeonRankRewardTable = Retrieve<DungeonRankRewardTable>(context, TableNames.DUNGEON_RANK_REWARD);
dungeonConfigTable = Retrieve<DungeonConfigTable>(context, TableNames.DUNGEON_CONFIG);
dungeonMissionTable = Retrieve<DungeonMissionTable>(context, TableNames.DUNGEON_MISSION);
seasonDataTable = Retrieve<SeasonDataTable>(context, TableNames.SEASON_DATA);
smartPushTable = Retrieve<SmartPushTable>(context, TableNames.SMART_PUSH);
autoActionTable = Retrieve<AutoActionTable>(context, TableNames.AUTO_ACTION);

}

private static Lazy<T> Retrieve<T>(MetadataContext context, string key) where T : Table {
Expand Down
2 changes: 1 addition & 1 deletion Maple2.File.Ingest/Maple2.File.Ingest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<ItemGroup>
<PackageReference Include="Crc32.NET" Version="1.2.0" />
<PackageReference Include="CsvHelper" Version="32.0.2" />
<PackageReference Include="Maple2.File.Parser.Tadeucci" Version="2.2.9" />
<PackageReference Include="Maple2.File.Parser.Tadeucci" Version="2.3.2" />
<PackageReference Include="DotRecast.Core" Version="2024.2.3" />
<PackageReference Include="DotRecast.Detour" Version="2024.2.3" />
<PackageReference Include="DotRecast.Recast" Version="2024.2.3" />
Expand Down
2 changes: 1 addition & 1 deletion Maple2.File.Ingest/Mapper/AchievementMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected override IEnumerable<AchievementMetadata> Map() {
Value: grade.condition.value == 0 ? 1 : grade.condition.value,
Codes: grade.condition.code.ConvertCodes(),
Target: grade.condition.target.ConvertCodes()),
Reward: grade.reward.type == AchieveRewardType.unknown ? null : new AchievementMetadataReward(
Reward: grade.reward is null || grade.reward.type == AchieveRewardType.unknown ? null : new AchievementMetadataReward(
Type: (AchievementRewardType) grade.reward.type,
Code: grade.reward.code,
Value: grade.reward.value,
Expand Down
2 changes: 1 addition & 1 deletion Maple2.File.Ingest/Mapper/AdditionalEffectMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ private static AdditionalEffectMetadataStatus Convert(StatusProperty status, Off
Element: (Element) dotDamage.element,
UseGrade: dotDamage.useGrade,
Rate: dotDamage.rate,
HpValue: dotDamage.value,
HpValue: (int) dotDamage.value,
SpValue: dotDamage.spValue,
EpValue: dotDamage.epValue,
DamageByTargetMaxHp: dotDamage.damageByTargetMaxHP,
Expand Down
10 changes: 6 additions & 4 deletions Maple2.File.Ingest/Mapper/ItemMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ namespace Maple2.File.Ingest.Mapper;
public class ItemMapper : TypeMapper<ItemMetadata> {
private readonly ItemParser parser;
private readonly TableParser tableParser;
private readonly bool newXml;
Comment thread
AngeloTadeucci marked this conversation as resolved.

public ItemMapper(M2dReader xmlReader) {
parser = new ItemParser(xmlReader);
tableParser = new TableParser(xmlReader);
public ItemMapper(M2dReader xmlReader, string language, bool newXml) {
parser = new ItemParser(xmlReader, language);
tableParser = new TableParser(xmlReader, language);
this.newXml = newXml;
}

protected override IEnumerable<ItemMetadata> Map() {
Expand All @@ -31,7 +33,7 @@ protected override IEnumerable<ItemMetadata> Map() {
}
}

foreach ((int id, string name, ItemData data) in parser.Parse<ItemDataRoot>()) {
foreach ((int id, string name, ItemData data) in parser.Parse()) {
int transferType = data.limit.transferType;
int tradableCount = data.property.tradableCount;
int tradableCountDeduction = data.property.tradableCountDeduction;
Expand Down
6 changes: 3 additions & 3 deletions Maple2.File.Ingest/Mapper/MapMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public class MapMapper : TypeMapper<MapMetadata> {
private readonly TableParser spawnParser;
private readonly MapParser parser;

public MapMapper(M2dReader xmlReader) {
spawnParser = new TableParser(xmlReader);
parser = new MapParser(xmlReader);
public MapMapper(M2dReader xmlReader, string language) {
spawnParser = new TableParser(xmlReader, language);
parser = new MapParser(xmlReader, language);
}

protected override IEnumerable<MapMetadata> Map() {
Expand Down
4 changes: 2 additions & 2 deletions Maple2.File.Ingest/Mapper/NpcMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Maple2.File.Ingest.Mapper;
public class NpcMapper : TypeMapper<NpcMetadata> {
private readonly NpcParser parser;

public NpcMapper(M2dReader xmlReader) {
parser = new NpcParser(xmlReader);
public NpcMapper(M2dReader xmlReader, string language) {
parser = new NpcParser(xmlReader, language);
}

protected override IEnumerable<NpcMetadata> Map() {
Expand Down
10 changes: 7 additions & 3 deletions Maple2.File.Ingest/Mapper/QuestMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ namespace Maple2.File.Ingest.Mapper;
public class QuestMapper : TypeMapper<QuestMetadata> {
private readonly QuestParser parser;

public QuestMapper(M2dReader xmlReader) {
parser = new QuestParser(xmlReader);
public QuestMapper(M2dReader xmlReader, string language) {
parser = new QuestParser(xmlReader, language);
}

protected override IEnumerable<QuestMetadata> Map() {
Expand Down Expand Up @@ -80,10 +80,14 @@ protected override IEnumerable<QuestMetadata> Map() {
PortalId: data.dispatch.portal,
Script: data.dispatch.script
),
Mentoring: data.mentoringMission == null ? null : new QuestMentoringMission(
Mentoring: data.mentoringMission == null || string.IsNullOrEmpty(data.mentoringMission.mentoringIcon) ? null : new QuestMentoringMission(
OpeningDay: data.mentoringMission.openingDay,
Season: data.mentoringMission.mentoringSeason
),
SummonPortal: data.summonPortal is { fieldID: 0, portalID: 0 } ? null : new QuestSummonPortal(
MapId: data.summonPortal.fieldID,
PortalId: data.summonPortal.portalID
),
EventMissionType: Enum.TryParse(data.eventMission.@event, true, out QuestEventMissionType eventMissionType) ? eventMissionType : QuestEventMissionType.none,
Conditions: data.condition.Select(condition => new ConditionMetadata(
Type: (ConditionType) condition.type,
Expand Down
4 changes: 2 additions & 2 deletions Maple2.File.Ingest/Mapper/ScriptMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace Maple2.File.Ingest.Mapper;
public class ScriptMapper : TypeMapper<ScriptMetadata> {
private readonly ScriptParser parser;

public ScriptMapper(M2dReader xmlReader) {
parser = new ScriptParser(xmlReader);
public ScriptMapper(M2dReader xmlReader, string language) {
parser = new ScriptParser(xmlReader, language);
}

protected override IEnumerable<ScriptMetadata> Map() {
Expand Down
14 changes: 14 additions & 0 deletions Maple2.File.Ingest/Mapper/ServerTableMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,20 @@ DayOfWeek ParseDayOfWeek(Maple2.File.Parser.Enum.DayOfWeek dayofWeek) {
return new MapleSurvivalOpenPeriod();
case GameEventType.ShutdownMapleSurvival:
return new ShutdownMapleSurvival();
case GameEventType.SaleAutoPlayInstrument:
if (!int.TryParse(value1, out int performanceDiscount) && string.IsNullOrEmpty(value2)) {
return null;
}
return new SaleAutoPlayInstrument(
Discount: performanceDiscount,
ContentType: value2);
case GameEventType.SaleAutoFishing:
if (!int.TryParse(value1, out int fishingDiscount) && string.IsNullOrEmpty(value2)) {
return null;
}
return new SaleAutoFishing(
Discount: fishingDiscount,
ContentType: value2);
Comment thread
Zintixx marked this conversation as resolved.
default:
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions Maple2.File.Ingest/Mapper/SkillMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Maple2.File.Ingest.Mapper;
public class SkillMapper : TypeMapper<StoredSkillMetadata> {
private readonly SkillParser parser;

public SkillMapper(M2dReader xmlReader) {
parser = new SkillParser(xmlReader);
public SkillMapper(M2dReader xmlReader, string language) {
parser = new SkillParser(xmlReader, language);
}

protected override IEnumerable<StoredSkillMetadata> Map() {
Expand Down
54 changes: 51 additions & 3 deletions Maple2.File.Ingest/Mapper/TableMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ namespace Maple2.File.Ingest.Mapper;
public class TableMapper : TypeMapper<TableMetadata> {
private readonly TableParser parser;
private readonly ItemOptionParser optionParser;
private readonly string language;

public TableMapper(M2dReader xmlReader) {
parser = new TableParser(xmlReader);
public TableMapper(M2dReader xmlReader, string language) {
parser = new TableParser(xmlReader, language);
optionParser = new ItemOptionParser(xmlReader);
}

Expand Down Expand Up @@ -82,6 +83,8 @@ protected override IEnumerable<TableMetadata> Map() {
yield return new TableMetadata { Name = TableNames.UGC_HOUSING_POINT_REWARD, Table = ParseUgcHousingPointRewardTable() };
yield return new TableMetadata { Name = TableNames.REWARD_CONTENT, Table = ParseRewardContentTable() };
yield return new TableMetadata { Name = TableNames.SEASON_DATA, Table = ParseSeasonDataTable() };
yield return new TableMetadata { Name = TableNames.SMART_PUSH, Table = ParseSmartPushTable() };
yield return new TableMetadata { Name = TableNames.AUTO_ACTION, Table = ParseAutoActionTable() };

// Marriage/Wedding
yield return new TableMetadata { Name = TableNames.WEDDING, Table = ParseWeddingTable() };
Expand Down Expand Up @@ -1771,8 +1774,53 @@ private SeasonDataTable ParseSeasonDataTable() {
seasonData.grade7,
]));
}

return results;
}
}

private SmartPushTable ParseSmartPushTable() {
var results = new Dictionary<int, SmartPushMetadata>();
foreach ((int id, SmartPush smartPush) in parser.ParseSmartPush()) {
var requiredItem = new IngredientInfo(ItemTag.None, 0);
var requiredItemTag = ItemTag.None;
if (smartPush.requireItem.Length != 0) {
string[] requiredItemArray = smartPush.requireItem[0].Split(":");
if (requiredItemArray.Length == 2) {
requiredItemTag = Enum.TryParse(requiredItemArray[1], out ItemTag tag) ? tag : ItemTag.None;
}
requiredItem = new IngredientInfo(
tag: requiredItemTag,
amount: int.Parse(smartPush.requireItem[2]));
}

results.Add(id, new SmartPushMetadata(
Id: id,
Content: smartPush.content,
Type: Enum.TryParse(smartPush.actionType, out SmartPushType type) ? type : SmartPushType.none,
Value: smartPush.actionValue,
MeretCost: smartPush.requireMerat,
RequiredItem: requiredItem));
}
return new SmartPushTable(results);
}

private AutoActionTable ParseAutoActionTable() {
var results = new Dictionary<string, IReadOnlyDictionary<int, AutoActionMetaData>>();
IEnumerable<IGrouping<string, AutoActionPricePackage>> groups = parser.ParseAutoActionPricePackage()
.Select(entry => entry.Data)
.GroupBy(entry => entry.content);
foreach (IGrouping<string, AutoActionPricePackage> group in groups) {
var packages = new Dictionary<int, AutoActionMetaData>();
foreach (AutoActionPricePackage package in group) {
packages.Add(package.id, new AutoActionMetaData(
Content: package.content,
Id: package.id,
Duration: package.duration,
MeretCost: package.merat,
MesoCost: package.meso));
}
results.Add(group.Key, packages);
}
return new AutoActionTable(results);
}
}
23 changes: 15 additions & 8 deletions Maple2.File.Ingest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Microsoft.EntityFrameworkCore;

const string locale = "NA";
string language = "en";
const string env = "Live";

Console.OutputEncoding = System.Text.Encoding.UTF8;
Expand All @@ -36,10 +37,16 @@
}

// Force Globalization to en-US because we use periods instead of commas for decimals
CultureInfo.CurrentCulture = new("en-US");
CultureInfo.CurrentCulture = new CultureInfo("en-US");

DotEnv.Load();

string? languageEnv = Environment.GetEnvironmentVariable("LANGUAGE");
if (languageEnv == null) {
throw new ArgumentException("LANGUAGE environment variable was not set");
}
language = languageEnv.ToLower();

string? ms2Root = Environment.GetEnvironmentVariable("MS2_DATA_FOLDER");
if (ms2Root == null) {
throw new ArgumentException("MS2_DATA_FOLDER environment variable was not set");
Expand Down Expand Up @@ -193,17 +200,17 @@

UpdateDatabase(metadataContext, new AdditionalEffectMapper(xmlReader));
UpdateDatabase(metadataContext, new AnimationMapper(xmlReader));
UpdateDatabase(metadataContext, new ItemMapper(xmlReader));
UpdateDatabase(metadataContext, new NpcMapper(xmlReader));
UpdateDatabase(metadataContext, new ItemMapper(xmlReader, language, false));
UpdateDatabase(metadataContext, new NpcMapper(xmlReader, language));
UpdateDatabase(metadataContext, new PetMapper(xmlReader));
UpdateDatabase(metadataContext, new MapMapper(xmlReader));
UpdateDatabase(metadataContext, new MapMapper(xmlReader, language));
UpdateDatabase(metadataContext, new UgcMapMapper(xmlReader));
UpdateDatabase(metadataContext, new ExportedUgcMapMapper(xmlReader));
UpdateDatabase(metadataContext, new QuestMapper(xmlReader));
UpdateDatabase(metadataContext, new QuestMapper(xmlReader, language));
UpdateDatabase(metadataContext, new RideMapper(xmlReader));
UpdateDatabase(metadataContext, new ScriptMapper(xmlReader));
UpdateDatabase(metadataContext, new SkillMapper(xmlReader));
UpdateDatabase(metadataContext, new TableMapper(xmlReader));
UpdateDatabase(metadataContext, new ScriptMapper(xmlReader, language));
UpdateDatabase(metadataContext, new SkillMapper(xmlReader, language));
UpdateDatabase(metadataContext, new TableMapper(xmlReader, language));
UpdateDatabase(metadataContext, new AchievementMapper(xmlReader));
UpdateDatabase(metadataContext, new FunctionCubeMapper(xmlReader));

Expand Down
2 changes: 2 additions & 0 deletions Maple2.Model/Common/TableNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public static class TableNames {
public const string WEDDING = "wedding*.xml";
public const string REWARD_CONTENT = "rewardcontent*.xml";
public const string SEASON_DATA = "seasondata*.xml";
public const string SMART_PUSH = "smartpush.xml";
public const string AUTO_ACTION = "autoactionpricepackage.xml";

// Prestige / Adventure
public const string PRESTIGE_LEVEL_ABILITY = "adventurelevelability.xml";
Expand Down
6 changes: 6 additions & 0 deletions Maple2.Model/Enum/CurrencyType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ public enum CurrencyType : byte {
StarPoint = 12,
MesoToken = 13,
}

public enum SmartPushCurrencyType {
None = 0,
Meso = 1,
Meret = 2,
}
1 change: 1 addition & 0 deletions Maple2.Model/Enum/Portal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum PortalType : byte {
DungeonReturnToLobby = 1,
Event = 3, // Pocket Realms & Player Hosted Mini games
FieldToHome = 5,
Quest = 6,
Boss = 8,
DungeonEnter = 9,
InHome = 11,
Expand Down
7 changes: 7 additions & 0 deletions Maple2.Model/Enum/SmartPushType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Maple2.Model.Enum;

public enum SmartPushType {
none,
additionalEffect,
autoInteraction
}
11 changes: 10 additions & 1 deletion Maple2.Model/Game/Event/GameEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,16 @@ public void WriteTo(IByteWriter writer) {
writer.WriteInt(steps);
writer.Write<RewardItem>(rewardItem);
}

break;
case SaleAutoFishing fishing:
writer.WriteInt(Id);
writer.WriteInt(fishing.Discount);
writer.WriteUnicodeString(fishing.ContentType);
break;
case SaleAutoPlayInstrument instrument:
writer.WriteInt(Id);
writer.WriteInt();
writer.WriteUnicodeString(instrument.ContentType);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Maple2.Model/Metadata/AdditionalEffectMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public record AdditionalEffectMetadataStatus(
IReadOnlyDictionary<SpecialAttribute, float> SpecialValues,
IReadOnlyDictionary<SpecialAttribute, float> SpecialRates,
IReadOnlyDictionary<BasicAttribute, float> Resistances,
long DeathResistanceHp,
bool DeathResistanceHp,
Comment thread
Zintixx marked this conversation as resolved.
AdditionalEffectMetadataStatus.CompulsionEvent? Compulsion,
AdditionalEffectMetadataStatus.StatConversion? Conversion,
int ImmuneBreak,
Expand Down
Loading