baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
// <copyright file="LocalizedStringConverter.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MUnique.OpenMU.Interfaces;
/// <summary>
/// A value converter for <see cref="LocalizedString" /> which stores only the underlying string value.
/// </summary>
internal class LocalizedStringConverter : ValueConverter<LocalizedString, string>
{
/// <summary>
/// Initializes a new instance of the <see cref="LocalizedStringConverter" /> class.
/// </summary>
private LocalizedStringConverter()
: base(value => value.Value ?? string.Empty, value => new LocalizedString(value))
{
}
/// <summary>
/// Gets the singleton instance of the <see cref="LocalizedStringConverter"/>.
/// </summary>
public static LocalizedStringConverter Instance { get; } = new();
}

View File

@@ -0,0 +1,27 @@
// <copyright file="AccountExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{Account}"/>.
/// </summary>
internal static class AccountExtensions
{
/// <summary>
/// Applies the settings for the <see cref="Account"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<Account> builder)
{
builder.Property(account => account.LoginName).HasMaxLength(10).IsRequired();
builder.HasIndex(account => account.LoginName).IsUnique();
builder.Property(account => account.LanguageIsoCode).HasMaxLength(3).IsRequired().HasDefaultValue("en");
}
}

View File

@@ -0,0 +1,32 @@
// <copyright file="AttributeExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="Attribute"/>-related <see cref="EntityTypeBuilder"/>s.
/// </summary>
internal static class AttributeExtensions
{
/// <summary>
/// Applies the settings for the <see cref="ConstValueAttribute"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ConstValueAttribute> builder)
{
builder.Ignore(c => c.AggregateType);
}
/// <summary>
/// Applies the settings for the <see cref="PowerUpDefinitionValue"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<PowerUpDefinitionValue> builder)
{
builder.Ignore(p => p.ConstantValue);
}
}

View File

@@ -0,0 +1,44 @@
// <copyright file="CharacterExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{Account}"/>.
/// </summary>
internal static class CharacterExtensions
{
/// <summary>
/// Applies the settings for the <see cref="Character"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<Character> builder)
{
builder.Property(character => character.Name).HasMaxLength(10).IsRequired();
builder.HasIndex(character => character.Name).IsUnique();
if (builder.Metadata.FindNavigation(nameof(Character.RawCharacterClass)) is { } navigation)
{
navigation.ForeignKey.IsRequired = true;
}
builder.Property(character => character.CharacterSlot).IsRequired();
builder.HasMany(character => character.RawLetters).WithOne(letter => letter.Receiver!).OnDelete(DeleteBehavior.Cascade);
}
/// <summary>
/// Applies the settings for the <see cref="CharacterClass"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<CharacterClass> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.HasMany(c => c.RawBaseAttributeValues)
.WithOne(c => c.CharacterClass);
}
}

View File

@@ -0,0 +1,23 @@
// <copyright file="ExitGateExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{ExitGate}"/>.
/// </summary>
internal static class ExitGateExtensions
{
/// <summary>
/// Applies the settings for the <see cref="ExitGate"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ExitGate> builder)
{
builder.HasOne(gate => gate.RawMap);
}
}

View File

@@ -0,0 +1,38 @@
// <copyright file="GameConfigurationExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{GameConfiguration}"/>.
/// </summary>
internal static class GameConfigurationExtensions
{
/// <summary>
/// Applies the settings for the <see cref="GameConfiguration"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<GameConfiguration> builder)
{
builder.Property(c => c.ItemDropDuration).HasDefaultValue(TimeSpan.FromSeconds(60));
builder.Property(c => c.ExcellentItemDropLevelDelta).HasDefaultValue((byte)25);
builder.Property(c => c.ExperienceFormula).HasDefaultValue("if(level == 0, 0, if(level < 256, 10 * (level + 8) * (level - 1) * (level - 1), (10 * (level + 8) * (level - 1) * (level - 1)) + (1000 * (level - 247) * (level - 256) * (level - 256))))");
builder.Property(c => c.MasterExperienceFormula).HasDefaultValue("(505 * level * level * level) + (35278500 * level) + (228045 * level * level)");
builder.HasMany(c => c.RawGlobalBaseAttributeValues).WithOne(c => c.GameConfiguration);
}
/// <summary>
/// Applies the settings for the <see cref="ConfigurationUpdate"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ConfigurationUpdate> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,36 @@
// <copyright file="GameMapDefinitionExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{GameMapDefinition}"/>.
/// </summary>
internal static class GameMapDefinitionExtensions
{
/// <summary>
/// Applies the settings for the <see cref="GameMapDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<GameMapDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.HasMany(map => map.RawEnterGates);
builder.HasMany(map => map.RawExitGates).WithOne(g => g.RawMap);
builder.HasOne(map => map.RawSafezoneMap);
builder.HasMany(map => map.RawMonsterSpawns);
}
/// <summary>
/// Applies the settings for the <see cref="WarpInfo"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<WarpInfo> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,133 @@
// <copyright file="ItemExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the item-related <see cref="EntityTypeBuilder"/>.
/// </summary>
internal static class ItemExtensions
{
/// <summary>
/// Applies the settings for the <see cref="ItemDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemStorage"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemStorage> builder)
{
builder.HasMany(storage => storage.RawItems).WithOne(item => item.RawItemStorage!);
}
/// <summary>
/// Applies the settings for the <see cref="ItemSetGroup"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemSetGroup> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.HasMany(isg => isg.RawItems).WithOne(item => item.RawItemSetGroup!);
}
/// <summary>
/// Applies the settings for the <see cref="ItemBasePowerUpDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemBasePowerUpDefinition> builder)
{
builder.Ignore(d => d.BaseValueElement);
}
/// <summary>
/// Applies the settings for the <see cref="ItemLevelBonusTable"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemLevelBonusTable> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemDropItemGroup"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemDropItemGroup> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="LevelBonus"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<LevelBonus> builder)
{
}
/// <summary>
/// Applies the settings for the <see cref="ItemSlotType"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemSlotType> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemOptionCombinationBonus"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemOptionCombinationBonus> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemOptionDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemOptionDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemOptionType"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemOptionType> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="ItemCrafting"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<ItemCrafting> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="DropItemGroup"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<DropItemGroup> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,32 @@
// <copyright file="LetterExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="EntityTypeBuilder{LetterBody}"/> and <see cref="EntityTypeBuilder{LetterHeader}"/>.
/// </summary>
internal static class LetterExtensions
{
/// <summary>
/// Applies the settings for the <see cref="LetterBody"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<LetterBody> builder)
{
builder.HasOne(body => body.RawHeader);
}
/// <summary>
/// Applies the settings for the <see cref="LetterHeader"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<LetterHeader> builder)
{
builder.Ignore(header => header.ReceiverName);
}
}

View File

@@ -0,0 +1,44 @@
// <copyright file="MiniGameExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="MiniGameDefinition"/>-related <see cref="EntityTypeBuilder"/>.
/// </summary>
internal static class MiniGameExtensions
{
/// <summary>
/// Applies the settings for the <see cref="MiniGameChangeEvent"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MiniGameChangeEvent> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Message).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="MiniGameSpawnWave"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MiniGameSpawnWave> builder)
{
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Message).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="MiniGameDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MiniGameDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
builder.Property(p => p.Description).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,34 @@
// <copyright file="MonsterExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="MonsterDefinition"/>-related <see cref="EntityTypeBuilder"/>s.
/// </summary>
internal static class MonsterExtensions
{
/// <summary>
/// Applies the settings for the <see cref="MonsterDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MonsterDefinition> builder)
{
builder.HasMany<QuestDefinition>().WithOne(q => q.RawQuestGiver);
builder.Property(m => m.Designation).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="MonsterSpawnArea"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MonsterSpawnArea> builder)
{
builder.HasOne(spawn => spawn.RawMonsterDefinition);
builder.HasOne(spawn => spawn.RawGameMap).WithMany(map => map.RawMonsterSpawns);
}
}

View File

@@ -0,0 +1,23 @@
// <copyright file="QuestExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the item-related <see cref="EntityTypeBuilder"/>.
/// </summary>
internal static class QuestExtensions
{
/// <summary>
/// Applies the settings for the <see cref="QuestDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<QuestDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,74 @@
// <copyright file="SkillExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MUnique.OpenMU.Persistence.EntityFramework.Model;
/// <summary>
/// Extensions for the <see cref="Skill"/>-related <see cref="EntityTypeBuilder"/>.
/// </summary>
internal static class SkillExtensions
{
/// <summary>
/// Applies the settings for the <see cref="Skill"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<Skill> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="Skill"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<SkillComboDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="SkillEntry"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<SkillEntry> builder)
{
builder.Ignore(s => s.PowerUps);
builder.Ignore(s => s.PowerUpsPvp);
builder.Ignore(s => s.PowerUpDuration);
builder.Ignore(s => s.PowerUpDurationPvp);
builder.Ignore(s => s.PowerUpChance);
builder.Ignore(s => s.PowerUpChancePvp);
builder.Ignore(s => s.Attributes);
}
/// <summary>
/// Applies the settings for the <see cref="MasterSkillRoot"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MasterSkillRoot> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
/// <summary>
/// Applies the settings for the <see cref="MasterSkillDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MasterSkillDefinition> builder)
{
builder.HasOne(s => s.RawRoot);
}
/// <summary>
/// Applies the settings for the <see cref="MagicEffectDefinition"/> entity.
/// </summary>
/// <param name="builder">The builder.</param>
public static void Apply(this EntityTypeBuilder<MagicEffectDefinition> builder)
{
builder.Property(p => p.Name).HasConversion(LocalizedStringConverter.Instance);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ModelBuilderExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions;
/// <summary>
/// Extensions for <see cref="Microsoft.EntityFrameworkCore.ModelBuilder"/>.
/// </summary>
internal static class ModelBuilderExtensions
{
/// <summary>
/// Configures the model builder to use UUID V7 as primary keys.
/// </summary>
/// <param name="modelBuilder">The model builder to configure.</param>
/// <returns>The configured model builder with UUID V7 key generation applied.</returns>
public static Microsoft.EntityFrameworkCore.ModelBuilder UseGuidV7Ids(this Microsoft.EntityFrameworkCore.ModelBuilder modelBuilder)
{
var types = modelBuilder.Model.GetEntityTypes();
foreach (var t in types)
{
var entity = modelBuilder.Entity(t.ClrType);
var key = entity.Metadata.FindProperty("Id");
if (key != null)
{
key.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAdd;
key.SetValueGeneratorFactory((_, _) => new GuidV7ValueGenerator());
}
}
return modelBuilder;
}
}